about summary refs log tree commit diff
path: root/app/models/account_stat.rb
diff options
context:
space:
mode:
authorEugen Rochko <eugen@zeonfederated.com>2019-10-02 04:59:37 +0200
committerGitHub <noreply@github.com>2019-10-02 04:59:37 +0200
commit62f60e86c281ae1cd0356a7630dbb76069e2ffde (patch)
tree9cf86a85bd836cab976dbff365a265f8735dd30f /app/models/account_stat.rb
parent9e3e3fa5ee3b63506e0fd6192c8357a012b98d7a (diff)
Fix account counters being overwritten by parallel writes (#12045)
Diffstat (limited to 'app/models/account_stat.rb')
-rw-r--r--app/models/account_stat.rb22
1 files changed, 22 insertions, 0 deletions
diff --git a/app/models/account_stat.rb b/app/models/account_stat.rb
index 1351f7d8a..c84e4217c 100644
--- a/app/models/account_stat.rb
+++ b/app/models/account_stat.rb
@@ -11,6 +11,7 @@
 #  created_at      :datetime         not null
 #  updated_at      :datetime         not null
 #  last_status_at  :datetime
+#  lock_version    :integer          default(0), not null
 #
 
 class AccountStat < ApplicationRecord
@@ -20,10 +21,26 @@ class AccountStat < ApplicationRecord
 
   def increment_count!(key)
     update(attributes_for_increment(key))
+  rescue ActiveRecord::StaleObjectError
+    begin
+      reload_with_id
+    rescue ActiveRecord::RecordNotFound
+      # Nothing to do
+    else
+      retry
+    end
   end
 
   def decrement_count!(key)
     update(key => [public_send(key) - 1, 0].max)
+  rescue ActiveRecord::StaleObjectError
+    begin
+      reload_with_id
+    rescue ActiveRecord::RecordNotFound
+      # Nothing to do
+    else
+      retry
+    end
   end
 
   private
@@ -33,4 +50,9 @@ class AccountStat < ApplicationRecord
     attrs[:last_status_at] = Time.now.utc if key == :statuses_count
     attrs
   end
+
+  def reload_with_id
+    self.id = find_by!(account: account).id if new_record?
+    reload
+  end
 end