diff options
author | Douwe Maan <douwe@selenight.nl> | 2017-06-01 16:35:32 -0500 |
---|---|---|
committer | Douwe Maan <douwe@selenight.nl> | 2017-06-02 11:43:32 -0500 |
commit | a9dbda8605f2c3111c4e4775edf7f931e4260a41 (patch) | |
tree | 4fb2253f569d1c670ac4ddba8d81733c154334cd /config | |
parent | 4edb505bb6783525444dd0179d1fb536a5cd1390 (diff) | |
download | gitlab-ce-a9dbda8605f2c3111c4e4775edf7f931e4260a41.tar.gz |
Allow scheduling from after_commit hooks
Diffstat (limited to 'config')
-rw-r--r-- | config/initializers/forbid_sidekiq_in_transactions.rb | 36 |
1 files changed, 27 insertions, 9 deletions
diff --git a/config/initializers/forbid_sidekiq_in_transactions.rb b/config/initializers/forbid_sidekiq_in_transactions.rb index 4eeb4ba4468..b22fb33748d 100644 --- a/config/initializers/forbid_sidekiq_in_transactions.rb +++ b/config/initializers/forbid_sidekiq_in_transactions.rb @@ -1,22 +1,24 @@ module Sidekiq module Worker + mattr_accessor :inside_after_commit + self.inside_after_commit = false + module ClassMethods module NoSchedulingFromTransactions NESTING = ::Rails.env.test? ? 1 : 0 %i(perform_async perform_at perform_in).each do |name| define_method(name) do |*args| - if ActiveRecord::Base.connection.open_transactions > NESTING - raise <<-MSG.strip_heredoc - `#{self}.#{name}` cannot be called inside a transaction as this can lead to race - conditions when the worker runs before the transaction is committed and tries to - access a model that has not been saved yet. + return super(*args) if Sidekiq::Worker.inside_after_commit + return super(*args) unless ActiveRecord::Base.connection.open_transactions > NESTING - Schedule the worker from inside a `run_after_commit` block instead. - MSG - end + raise <<-MSG.strip_heredoc + `#{self}.#{name}` cannot be called inside a transaction as this can lead to + race conditions when the worker runs before the transaction is committed and + tries to access a model that has not been saved yet. - super(*args) + Use an `after_commit` hook, or include `AfterCommitQueue` and use a `run_after_commit` block instead. + MSG end end end @@ -25,3 +27,19 @@ module Sidekiq end end end + +module ActiveRecord + class Base + module InsideAfterCommit + def committed!(*) + inside_after_commit = Sidekiq::Worker.inside_after_commit + Sidekiq::Worker.inside_after_commit = true + super + ensure + Sidekiq::Worker.inside_after_commit = inside_after_commit + end + end + + prepend InsideAfterCommit + end +end |