Commit 7c032c47 authored by Heinrich Lee Yu's avatar Heinrich Lee Yu

Change Shard to use safe_find_or_create_by

Using this method allows us to benefit from a recent optimization where
the transaction is skipped in the most common scenario where the record
is found on the first attempt
parent 93d73652
...@@ -18,10 +18,6 @@ class Shard < ApplicationRecord ...@@ -18,10 +18,6 @@ class Shard < ApplicationRecord
end end
def self.by_name(name) def self.by_name(name)
transaction(requires_new: true) do safe_find_or_create_by(name: name)
find_or_create_by(name: name)
end
rescue ActiveRecord::RecordNotUnique
retry
end end
end end
...@@ -33,19 +33,21 @@ RSpec.describe Shard do ...@@ -33,19 +33,21 @@ RSpec.describe Shard do
expect(result.name).to eq('foo') expect(result.name).to eq('foo')
end end
it 'retries if creation races' do it 'returns existing record if creation races' do
shard_created_by_others = double(described_class)
expect(described_class) expect(described_class)
.to receive(:find_or_create_by) .to receive(:find_by)
.with(name: 'default') .with(name: 'new_shard')
.and_raise(ActiveRecord::RecordNotUnique, 'fail') .and_return(nil, shard_created_by_others)
.once
expect(described_class) expect(described_class)
.to receive(:find_or_create_by) .to receive(:create)
.with(name: 'default') .with(name: 'new_shard')
.and_call_original .and_raise(ActiveRecord::RecordNotUnique, 'fail')
.once
expect(described_class.by_name('default')).to eq(default_shard) expect(described_class.by_name('new_shard')).to eq(shard_created_by_others)
end end
end end
end end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment