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