mirror of
https://github.com/discourse/discourse.git
synced 2024-11-25 10:20:58 -06:00
DEV: Always enqueue sidekiq jobs after database transaction commit (#11293)
When jobs are enqueued inside a transaction, it's possible that they will be executed before the necessary data is available in the database. This commit ensures all jobs are enqueued in an ActiveRecord after_commit hook. One potential downside here is if the job fails to enqueue, the transaction will no longer be aborted. However, the chance of that happening is reasonably low, and the impact is significantly lower than the current issue where jobs are scheduled before their data is ready.
This commit is contained in:
parent
ed91385c18
commit
c69bb5d5be
@ -311,7 +311,7 @@ module Jobs
|
||||
hash['queue'] = queue
|
||||
end
|
||||
|
||||
klass.client_push(hash)
|
||||
DB.after_commit { klass.client_push(hash) }
|
||||
else
|
||||
# Otherwise execute the job right away
|
||||
opts.delete(:delay_for)
|
||||
|
@ -29,6 +29,28 @@ describe Jobs do
|
||||
end
|
||||
end
|
||||
|
||||
it "enqueues the job after the current transaction has committed" do
|
||||
jobs = Jobs::ProcessPost.jobs
|
||||
expect(jobs.length).to eq(0)
|
||||
|
||||
Jobs.enqueue(:process_post, post_id: 1)
|
||||
expect(jobs.length).to eq(1)
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
Jobs.enqueue(:process_post, post_id: 1)
|
||||
expect(jobs.length).to eq(1)
|
||||
end
|
||||
expect(jobs.length).to eq(2)
|
||||
|
||||
# Failed transation
|
||||
ActiveRecord::Base.transaction do
|
||||
Jobs.enqueue(:process_post, post_id: 1)
|
||||
raise ActiveRecord::Rollback
|
||||
end
|
||||
|
||||
expect(jobs.length).to eq(2) # No change
|
||||
end
|
||||
|
||||
it "does not pass current_site_id when 'all_sites' is present" do
|
||||
Sidekiq::Testing.fake! do
|
||||
jobs = Jobs::ProcessPost.jobs
|
||||
|
Loading…
Reference in New Issue
Block a user