Add common ThreadingHelper module for specs (#29116)

This commit is contained in:
Matt Jankowski 2024-02-07 09:53:29 -05:00 committed by GitHub
parent dbafec88e5
commit 95da28d201
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 40 additions and 57 deletions

View file

@ -33,18 +33,14 @@ describe RequestPool do
subject subject
threads = Array.new(5) do multi_threaded_execution(5) do
Thread.new do subject.with('http://example.com') do |http_client|
subject.with('http://example.com') do |http_client| http_client.get('/').flush
http_client.get('/').flush # Nudge scheduler to yield and exercise the full pool
# Nudge scheduler to yield and exercise the full pool sleep(0.01)
sleep(0.01)
end
end end
end end
threads.map(&:join)
expect(subject.size).to be > 1 expect(subject.size).to be > 1
end end

View file

@ -1035,19 +1035,10 @@ RSpec.describe Account do
it 'increments the count in multi-threaded an environment when account_stat is not yet initialized' do it 'increments the count in multi-threaded an environment when account_stat is not yet initialized' do
subject subject
increment_by = 15 multi_threaded_execution(15) do
wait_for_start = true described_class.find(subject.id).increment_count!(:followers_count)
threads = Array.new(increment_by) do
Thread.new do
true while wait_for_start
described_class.find(subject.id).increment_count!(:followers_count)
end
end end
wait_for_start = false
threads.each(&:join)
expect(subject.reload.followers_count).to eq 15 expect(subject.reload.followers_count).to eq 15
end end
end end

View file

@ -6,6 +6,8 @@ describe Account::Counters do
let!(:account) { Fabricate(:account) } let!(:account) { Fabricate(:account) }
describe '#increment_count!' do describe '#increment_count!' do
let(:increment_by) { 15 }
it 'increments the count' do it 'increments the count' do
expect(account.followers_count).to eq 0 expect(account.followers_count).to eq 0
account.increment_count!(:followers_count) account.increment_count!(:followers_count)
@ -13,24 +15,17 @@ describe Account::Counters do
end end
it 'increments the count in multi-threaded an environment' do it 'increments the count in multi-threaded an environment' do
increment_by = 15 multi_threaded_execution(increment_by) do
wait_for_start = true account.increment_count!(:statuses_count)
threads = Array.new(increment_by) do
Thread.new do
true while wait_for_start
account.increment_count!(:statuses_count)
end
end end
wait_for_start = false
threads.each(&:join)
expect(account.statuses_count).to eq increment_by expect(account.statuses_count).to eq increment_by
end end
end end
describe '#decrement_count!' do describe '#decrement_count!' do
let(:decrement_by) { 10 }
it 'decrements the count' do it 'decrements the count' do
account.followers_count = 15 account.followers_count = 15
account.save! account.save!
@ -40,22 +35,13 @@ describe Account::Counters do
end end
it 'decrements the count in multi-threaded an environment' do it 'decrements the count in multi-threaded an environment' do
decrement_by = 10
wait_for_start = true
account.statuses_count = 15 account.statuses_count = 15
account.save! account.save!
threads = Array.new(decrement_by) do multi_threaded_execution(decrement_by) do
Thread.new do account.decrement_count!(:statuses_count)
true while wait_for_start
account.decrement_count!(:statuses_count)
end
end end
wait_for_start = false
threads.each(&:join)
expect(account.statuses_count).to eq 5 expect(account.statuses_count).to eq 5
end end
end end

View file

@ -86,6 +86,7 @@ RSpec.configure do |config|
config.include ActiveSupport::Testing::TimeHelpers config.include ActiveSupport::Testing::TimeHelpers
config.include Chewy::Rspec::Helpers config.include Chewy::Rspec::Helpers
config.include Redisable config.include Redisable
config.include ThreadingHelpers
config.include SignedRequestHelpers, type: :request config.include SignedRequestHelpers, type: :request
config.include CommandLineHelpers, type: :cli config.include CommandLineHelpers, type: :cli

View file

@ -219,27 +219,19 @@ RSpec.describe ResolveAccountService, type: :service do
end end
it 'processes one remote account at a time using locks' do it 'processes one remote account at a time using locks' do
wait_for_start = true
fail_occurred = false fail_occurred = false
return_values = Concurrent::Array.new return_values = Concurrent::Array.new
threads = Array.new(5) do multi_threaded_execution(5) do
Thread.new do begin
true while wait_for_start return_values << described_class.new.call('foo@ap.example.com')
rescue ActiveRecord::RecordNotUnique
begin fail_occurred = true
return_values << described_class.new.call('foo@ap.example.com') ensure
rescue ActiveRecord::RecordNotUnique RedisConfiguration.pool.checkin if Thread.current[:redis]
fail_occurred = true
ensure
RedisConfiguration.pool.checkin if Thread.current[:redis]
end
end end
end end
wait_for_start = false
threads.each(&:join)
expect(fail_occurred).to be false expect(fail_occurred).to be false
expect(return_values).to_not include(nil) expect(return_values).to_not include(nil)
end end

View file

@ -0,0 +1,17 @@
# frozen_string_literal: true
module ThreadingHelpers
def multi_threaded_execution(thread_count)
wait_for_start = true
threads = Array.new(thread_count) do
Thread.new do
true while wait_for_start
yield
end
end
wait_for_start = false
threads.each(&:join)
end
end