FIX: handle concurrently creating post reply keys

In some very rare conditions this would be called concurrently and fail
This commit is contained in:
Sam 2018-08-21 10:59:18 +10:00
parent 8fa5dd4a1f
commit ca5a6f0a9d
2 changed files with 14 additions and 1 deletions

View File

@ -262,7 +262,8 @@ module Email
post_id &&
header_value(Email::MessageBuilder::ALLOW_REPLY_BY_EMAIL_HEADER).present?
reply_key = PostReplyKey.find_or_create_by!(
# use safe variant here cause we tend to see concurrency issue
reply_key = PostReplyKey.find_or_create_by_safe!(
post_id: post_id,
user_id: user_id
).reply_key

View File

@ -1,5 +1,17 @@
class ActiveRecord::Base
# Handle PG::UniqueViolation as well due to concurrency
# find_or_create does find_by(hash) || create!(hash)
# in some cases find will not find and multiple creates will be called
def self.find_or_create_by_safe!(hash)
begin
find_or_create_by!(hash)
rescue PG::UniqueViolation
# try again cause another transaction could have passed by now
find_or_create_by!(hash)
end
end
# Execute SQL manually
def self.exec_sql(*args)