This is a continuation of #182 - for which I supplied a bugfix a few years back. We are still seeing a race condition, but this one is much rarer.
When concurrently creating / deleting items, it can happen that rearrange_ranks raises an error because the reason for the rearranging has been deleted in the meantime. This can be reproduced pretty consistently with the following script:
begin
require "bundler/inline"
rescue LoadError => e
$stderr.puts "Bundler version 1.10 or later is required. Please update your Bundler"
raise e
end
gemfile(true) do
source "https://rubygems.org"
gem "activerecord", "~> 7.1"
gem "ranked-model"
gem "pg"
gem 'byebug'
end
require "active_record"
require "minitest/autorun"
require "logger"
# This connection will do for database-independent bug reports.
ActiveRecord::Base.establish_connection(adapter: "postgresql", database: "ranked_model_issue", url: "postgres://postgres:@localhost:5434")
ActiveRecord::Base.logger = Logger.new(STDOUT)
ActiveRecord::Schema.define do
create_table :ducks, force: true do |t|
t.string :name
t.integer :row_order
t.timestamps
end
end
class Duck < ActiveRecord::Base
include RankedModel
ranks :row_order
end
class BugTest < Minitest::Test
def test_no_duplicate_row_values
10.times do
threads = 20.times.map do
Thread.new do
ActiveRecord::Base.connection_pool.with_connection do
duck = Duck.create!
duck.destroy
end
end
end
threads.each(&:join)
end
end
end
I solved this in my app by making the following change to rearrange_ranks:
def rearrange_ranks
reset_cache
return if current_first.nil? || current_last.nil?
# ...
Meaning if there's no current_first or current_last we can just skip rearranging, as there's nothing to re-arrange anymore.
This is a continuation of #182 - for which I supplied a bugfix a few years back. We are still seeing a race condition, but this one is much rarer.
When concurrently creating / deleting items, it can happen that
rearrange_ranksraises an error because the reason for the rearranging has been deleted in the meantime. This can be reproduced pretty consistently with the following script:I solved this in my app by making the following change to
rearrange_ranks:Meaning if there's no current_first or current_last we can just skip rearranging, as there's nothing to re-arrange anymore.