Skip to content

Commit cab2e1d

Browse files
ClearlyClaireGargron
authored andcommitted
Add optimistic lock to avoid race conditions when handling votes (mastodon#10196)
* Add optimistic lock to avoid race conditions when handling votes * Force-reload polls when getting `ActiveRecord::StaleObjectError`
1 parent ed04c4c commit cab2e1d

4 files changed

Lines changed: 12 additions & 1 deletion

File tree

app/models/poll.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
# last_fetched_at :datetime
1616
# created_at :datetime not null
1717
# updated_at :datetime not null
18+
# lock_version :integer default(0), not null
1819
#
1920

2021
class Poll < ApplicationRecord

app/models/poll_vote.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,8 @@ def object_type
3232
def increment_counter_cache
3333
poll.cached_tallies[choice] = (poll.cached_tallies[choice] || 0) + 1
3434
poll.save
35+
rescue ActiveRecord::StaleObjectError
36+
poll.reload
37+
retry
3538
end
3639
end
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
class AddLockVersionToPolls < ActiveRecord::Migration[5.2]
2+
def change
3+
add_column :polls, :lock_version, :integer, null: false, default: 0
4+
end
5+
end
6+

db/schema.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
#
1111
# It's strongly recommended that you check this file into your version control system.
1212

13-
ActiveRecord::Schema.define(version: 2019_03_04_152020) do
13+
ActiveRecord::Schema.define(version: 2019_03_06_145741) do
1414

1515
# These are extensions that must be enabled in order to support this database
1616
enable_extension "plpgsql"
@@ -464,6 +464,7 @@
464464
t.datetime "last_fetched_at"
465465
t.datetime "created_at", null: false
466466
t.datetime "updated_at", null: false
467+
t.integer "lock_version", default: 0, null: false
467468
t.index ["account_id"], name: "index_polls_on_account_id"
468469
t.index ["status_id"], name: "index_polls_on_status_id"
469470
end

0 commit comments

Comments
 (0)