Skip to content
This repository has been archived by the owner on Nov 8, 2022. It is now read-only.

Commit

Permalink
fix redis race conditions: use MERGE instead of CREATE
Browse files Browse the repository at this point in the history
  • Loading branch information
kfarwell committed Jan 26, 2022
1 parent dced971 commit fa175b0
Show file tree
Hide file tree
Showing 12 changed files with 61 additions and 53 deletions.
3 changes: 2 additions & 1 deletion app/site/confirm.es
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ if {isempty $expiry} {
# Create confirmation with expiry in 24 hours
redis graph write 'MATCH (u:user {username: '''$u'''})
CREATE (u)-[:CONFIRM]->(c:confirm {id: '''$confirm''', expiry: '`{+ $dateun 86400}^'})'
MERGE (c:confirm {id: '''$confirm''', expiry: '`{+ $dateun 86400}^'})
MERGE (u)-[:CONFIRM]->(c)'

throw error 'Your confirmation link has expired. We''ve sent you a new one. Please check your email and confirm again'
}
Expand Down
3 changes: 2 additions & 1 deletion app/site/forgot.es
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ sed 's/\$reset/'$reset'/' < mail/reset | email $username 'Password reset request
# Create reset
redis graph write 'MATCH (u:user {username: '''$username'''})
CREATE (u)-[:RESET]->(r:reset {id: '''$reset''', expiry: '`{+ $dateun 86400}^'})'
MERGE (r:reset {id: '''$reset''', expiry: '`{+ $dateun 86400}^'})
MERGE (u)-[:RESET]->(r)'

forgot_success = true
26 changes: 14 additions & 12 deletions app/site/g/create.es
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,16 @@ if {!~ $p_type public && !~ $p_type private} {

# Create group
redis graph write 'MATCH (u:user {username: '''$logged_user'''})
CREATE (u)-[:ADMINS]->(g:group {name: '''`^{echo $^p_name | escape_redis}^''',
url: '''$p_url''',
description: '''`^{echo $p_description |
sed 's/\\//g' | bluemonday |
sed 's/<a /<a onclick="external_link(event, this)" /g' |
escape_redis}^''',
type: '''$p_type''',
invite: '''`^{kryptgo genid}^'''}),
(u)-[:MEMBER]->(g)'
MERGE (g:group {name: '''`^{echo $^p_name | escape_redis}^''',
url: '''$p_url''',
description: '''`^{echo $p_description |
sed 's/\\//g' | bluemonday |
sed 's/<a /<a onclick="external_link(event, this)" /g' |
escape_redis}^''',
type: '''$p_type''',
invite: '''`^{kryptgo genid}^'''})
MERGE (u)-[:ADMINS]->(g)
MERGE (u)-[:MEMBER]->(g)'
# Validate and write interests
defaultset = false
Expand All @@ -41,7 +42,7 @@ for (tag = `{echo $^p_interests_default | sed 's/ /_/g; s/,/ /g'}) {
redis graph write 'MATCH (g:group {url: '''$p_url'''}),
(t:tag {name: '''$tag'''})
WHERE t.category <> ''custom''
CREATE (g)-[:TAGGED]->(t)'
MERGE (g)-[:TAGGED]->(t)'
}
}
if {~ $defaultset false} {
Expand All @@ -55,12 +56,13 @@ for (tag = `{echo $^p_interests_custom | sed 's/ /_/g; s/,/ /g' | escape_redis})
if {isempty $existingtag} {
# Create new tag
redis graph write 'MATCH (g:group {url: '''$p_url'''})
CREATE (g)-[:TAGGED]->(t:tag {name: '''$tag''', category: ''custom''})'
MERGE (t:tag {name: '''$tag''', category: ''custom''})
MERGE (g)-[:TAGGED]->(t)'
} {
# Existing tag; link to group
redis graph write 'MATCH (g:group {url: '''$p_url'''}),
(t:tag {name: '''$existingtag''', category: ''custom''})
CREATE (g)-[:TAGGED]->(t)'
MERGE (g)-[:TAGGED]->(t)'
}
}
Expand Down
2 changes: 1 addition & 1 deletion app/site/g/membership.es
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ if {! echo $p_group | grep -s '^[a-zA-Z0-9_\-]+$' ||
if {~ $p_action join} {
redis graph write 'MATCH (u:user {username: '''$logged_user'''}),
(g:group {invite: '''$p_group'''})
CREATE (u)-[:MEMBER]->(g)'
MERGE (u)-[:MEMBER]->(g)'
} {~ $p_action leave} {
# Admins can't leave groups
if {~ `{redis graph read 'MATCH (u:user {username: '''$logged_user'''})-[a:ADMINS]->(g:group {invite: '''$p_group'''})
Expand Down
6 changes: 3 additions & 3 deletions app/site/managegames.es
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ p_name = `{echo $^p_name | sed 's/''//g; s/ /_/g'}
# Create game if it doesn't already exist
if {!~ `{redis graph read 'MATCH (g:game {name: '''$^p_name'''}) RETURN exists(g)'} true} {
redis graph write 'CREATE (g:game {name: '''$p_name'''})'
redis graph write 'MERGE (g:game {name: '''$p_name'''})'
}
# Set type
Expand Down Expand Up @@ -60,7 +60,7 @@ for (category = social gaming genre life creation) {
for (tag = $(tags_$category)) {
redis graph write 'MATCH (g:game {name: '''$p_name'''}),
(t:tag {name: '''$tag''', category: '''$category'''})
CREATE (g)-[:TAGGED]->(t)'
MERGE (g)-[:TAGGED]->(t)'
}
}
Expand All @@ -69,6 +69,6 @@ for (platform = `{redis graph read 'MATCH (p:platform) RETURN p.name'}) {
if {~ $(p_$platform) true} {
redis graph write 'MATCH (g:game {name: '''$p_name'''}),
(p:platform {name: '''$platform'''})
CREATE (g)-[:SUPPORTS]->(p)'
MERGE (g)-[:SUPPORTS]->(p)'
}
}
7 changes: 4 additions & 3 deletions app/site/onboarding/1.es
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ for (category = social gaming genre life creation) {
for (tag = $(tags_$category)) {
redis graph write 'MATCH (u:user {username: '''$logged_user'''}),
(t:tag {name: '''$tag''', category: '''$category'''})
CREATE (u)-[:INTERESTED_IN]->(t)'
MERGE (u)-[:INTERESTED_IN]->(t)'
}
}
Expand All @@ -72,12 +72,13 @@ if {! isempty $p_custom} {
if {isempty $existingtag} {
# Create new tag
redis graph write 'MATCH (u:user {username: '''$logged_user'''})
CREATE (u)-[:INTERESTED_IN]->(t:tag {name: '''$tag''', category: ''custom''})'
MERGE (t:tag {name: '''$tag''', category: ''custom''})
MERGE (u)-[:INTERESTED_IN]->(t)'
} {
# Existing tag; link to user
redis graph write 'MATCH (u:user {username: '''$logged_user'''}),
(t:tag {name: '''$existingtag''', category: ''custom''})
CREATE (u)-[:INTERESTED_IN]->(t)'
MERGE (u)-[:INTERESTED_IN]->(t)'
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions app/site/onboarding/3.es
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ if {! isempty $p_country} {
}
redis graph write 'MATCH (u:user {username: '''$logged_user'''}),
(c:country {id: '''$p_country'''})
CREATE (u)-[:COUNTRY]->(c)'
MERGE (u)-[:COUNTRY]->(c)'
} {
redis graph write 'MATCH (u:user {username: '''$logged_user'''})-[r:COUNTRY]->(c:country)
DELETE r'
Expand All @@ -74,7 +74,7 @@ for (language = `{echo $^p_language | sed 's/ /_/g; s/,/ /g'}) {
languageset = true
redis graph write 'MATCH (u:user {username: '''$logged_user'''}),
(l:language {id: '''$language'''})
CREATE (u)-[:KNOWS]->(l)'
MERGE (u)-[:KNOWS]->(l)'
}
}
if {~ $languageset false} {
Expand All @@ -89,7 +89,7 @@ for (platform = `{redis graph read 'MATCH (p:platform) RETURN p.name'}) {
platformset = true
redis graph write 'MATCH (u:user {username: '''$logged_user'''}),
(p:platform {name: '''$platform'''})
CREATE (u)-[:USES]->(p)'
MERGE (u)-[:USES]->(p)'
}
}
if {~ $platformset false} {
Expand Down
2 changes: 1 addition & 1 deletion app/site/onboarding/4.es
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ for (game = `{echo $^p_games | sed 's/ /_/g; s/,/ /g'}) {
if {in $game $games} {
redis graph write 'MATCH (u:user {username: '''$logged_user'''}),
(g:game {name: '''$game'''})
CREATE (u)-[:PLAYS]->(g)'
MERGE (u)-[:PLAYS]->(g)'
}
}
Expand Down
6 changes: 4 additions & 2 deletions app/site/onboarding/7.es
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ if {~ $p_resend yes} {
# Create confirmation with expiry in 24 hours
redis graph write 'MATCH (u:user {username: '''$logged_user'''})
CREATE (u)-[:CONFIRM]->(c:confirm {id: '''$confirm''', expiry: '`{+ $dateun 86400}^'})'
MERGE (c:confirm {id: '''$confirm''', expiry: '`{+ $dateun 86400}^'})
MERGE (u)-[:CONFIRM]->(c)'
} {! isempty $p_email} {
# Change email
# Format email, check availability
Expand All @@ -36,7 +37,8 @@ if {~ $p_resend yes} {
# Update email and create confirmation with expiry in 24 hours
redis graph write 'MATCH (u:user {username: '''$logged_user'''})
SET u.email = '''$p_email'''
CREATE (u)-[:CONFIRM]->(c:confirm {id: '''$confirm''', expiry: '`{+ $dateun 86400}^'})'
MERGE (c:confirm {id: '''$confirm''', expiry: '`{+ $dateun 86400}^'})
MERGE (u)-[:CONFIRM]->(c)'
# Email confirmation
sed 's/\$confirm/'$confirm'/' < mail/confirm | email $logged_user 'Please confirm your email'
Expand Down
46 changes: 23 additions & 23 deletions app/site/register.es
Original file line number Diff line number Diff line change
Expand Up @@ -47,25 +47,25 @@ if {! hcaptcha $p_hcaptcharesponse} {
# Create user and confirmation
confirm = `{kryptgo genid}
redis graph write 'CREATE (u:user {username: '''$p_username''',
email: '''$p_email''',
password: '''`{kryptgo genhash -p $p_password}^''',
newsletter: '$p_newsletter',
email_wave: ''each'',
onboarding: 1,
privacy_age: ''rovr'', privacy_gender: ''rovr'',
privacy_country: ''public'', privacy_interests_common: ''rovr'',
privacy_interests_uncommon: ''public'', privacy_bio: ''public'',
privacy_language: ''public'', privacy_platform: ''public'',
privacy_games: ''public'', privacy_socials: ''public'',
privacy_friends: ''friends'', privacy_invite: ''public'',
optout: false,
theme: '''$p_theme''',
avatar: ''defaults/01'',
volume: 0.5,
registered: '''`{date -ui}^'''})
-[:CONFIRM]->
(c:confirm {id: '''$confirm''', expiry: '`{+ $dateun 86400}^'})'
redis graph write 'MERGE (u:user {username: '''$p_username''',
email: '''$p_email''',
password: '''`{kryptgo genhash -p $p_password}^''',
newsletter: '$p_newsletter',
email_wave: ''each'',
onboarding: 1,
privacy_age: ''rovr'', privacy_gender: ''rovr'',
privacy_country: ''public'', privacy_interests_common: ''rovr'',
privacy_interests_uncommon: ''public'', privacy_bio: ''public'',
privacy_language: ''public'', privacy_platform: ''public'',
privacy_games: ''public'', privacy_socials: ''public'',
privacy_friends: ''friends'', privacy_invite: ''public'',
optout: false,
theme: '''$p_theme''',
avatar: ''defaults/01'',
volume: 0.5,
registered: '''`{date -ui}^'''})
MERGE (c:confirm {id: '''$confirm''', expiry: '`{+ $dateun 86400}^'})
MERGE (u)-[:CONFIRM]->(c)'
# Email confirmation
sed 's/\$confirm/'$confirm'/' < mail/confirm | email $p_username 'Please confirm your email'
Expand All @@ -74,13 +74,13 @@ sed 's/\$confirm/'$confirm'/' < mail/confirm | email $p_username 'Please confirm
redis graph write 'MATCH (u:user {username: '''$p_username'''}),
(r:referral {id: '''`^{echo $p_referred_via | tr 'a-z' 'A-Z'}^'''}),
(ru:user)-[:REFERRAL]->(r)
CREATE (u)-[:REFERRED_BY]->(ru),
(u)-[:REFERRED_VIA]->(r)
SET r.uses = r.uses - 1'
MERGE (u)-[:REFERRED_BY]->(ru)
MERGE (u)-[:REFERRED_VIA]->(r)'
# Create referral for new user
referral = `{kryptgo genid -l 6 | sed 's/-/A/g; s/_/B/g' | tr 'a-z' 'A-Z'}
redis graph write 'MATCH (u:user {username: '''$p_username'''})
CREATE (u)-[:REFERRAL]->(r:referral {id: '''$referral''', uses: 10})'
MERGE (r:referral {id: '''$referral'''})
MERGE (u)-[:REFERRAL]->(r)'
login_user $p_username $p_password
3 changes: 2 additions & 1 deletion app/site/settings.es
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ if {~ $p_changeemail true &&
SET u.email = '''$p_newemail''',
u.confirmed = false,
u.onboarding = 7
CREATE (u)-[:CONFIRM]->(c:confirm {id: '''$confirm''', expiry: '`{+ $dateun 86400}^'})'
MERGE (c:confirm {id: '''$confirm''', expiry: '`{+ $dateun 86400}^'})
MERGE (u)-[:CONFIRM]->(c)'
# Email confirmation
sed 's/\$confirm/'$confirm'/' < mail/confirm | email $logged_user 'Please confirm your email'
Expand Down
4 changes: 2 additions & 2 deletions app/site/wave.es
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ if {~ `{redis graph read 'MATCH (a:user {username: '''$p_user'''})-[r:WAVED]->(b
# User had already waved at logged_user, add friend
redis graph write 'MATCH (a:user {username: '''$p_user'''})-[r:WAVED]->(b:user {username: '''$logged_user'''})
DELETE r
CREATE (a)-[:FRIENDS {new: true}]->(b)'
MERGE (a)-[:FRIENDS {new: true}]->(b)'
xmpp add_rosteritem '{"localuser": "'$logged_user'", "localhost": "'$XMPP_HOST'", "user": "'$p_user'", "host": "'$XMPP_HOST'", "nick": "'$p_user'", "group": "Friends", "subs": "both"}'
xmpp add_rosteritem '{"localuser": "'$p_user'", "localhost": "'$XMPP_HOST'", "user": "'$logged_user'", "host": "'$XMPP_HOST'", "nick": "'$logged_user'", "group": "Friends", "subs": "both"}'
Expand All @@ -29,7 +29,7 @@ if {~ `{redis graph read 'MATCH (a:user {username: '''$p_user'''})-[r:WAVED]->(b
# Create new wave
redis graph write 'MATCH (a:user {username: '''$logged_user'''}),
(b:user {username: '''$p_user'''})
CREATE (a)-[:WAVED {email: true}]->(b)'
MERGE (a)-[:WAVED {email: true}]->(b)'
# Email notification
send = `{redis graph read 'MATCH (u:user {username: '''$p_user'''}) RETURN u.email_wave'}
Expand Down

0 comments on commit fa175b0

Please sign in to comment.