Created
September 8, 2016 13:25
-
-
Save brandonhilkert/cb85b2820505bf126e97bfb9e835b1af to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class IncrementConnectionStatWorker | |
include Sidekiq::Worker | |
def perform(activity_id) | |
a = Activity.find(activity_id) | |
# I had previously used .find_or_initialize_by | |
# but that proved to not be thread-safe on the incrementing | |
stat = ConnectionStat.find_by( | |
day: Time.zone.now.to_date, | |
connection_id: a.connection_id | |
) | |
if stat.present? | |
# Pessimistic locking here seemed | |
# to do the trick removing race conditions | |
# when incrementing | |
stat.with_lock do | |
stat.activities_analyzed += 1 | |
stat.save! | |
end | |
else | |
# It's possible the presence check for ConnectionStat | |
# could be susceptible to a race condition, so I created | |
# a compount unique index on [:day, :connection_id] -- | |
# causing the insert to fail, the job to retry and properly | |
# go down the path of incrementing the existing record | |
ConnectionStat.create!( | |
day: Time.zone.now.to_date, | |
connection_id: a.connection_id, | |
activities_analyzed: 1 | |
) | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment