Skip to content

Commit ba61580

Browse files
y-yagibyroot
authored andcommitted
Allow to set enqueue_after_transaction_commit to jobs when eager_load is true
The current code expects `active_record` to be loaded before `active_job`. But I think there are no guarantees about load orders. At least, `active_job` is loaded before `active_record` in a newer application. In that case, `EnqueueAfterTransactionCommit` isn't loaded and an application that uses `enqueue_after_transaction_commit` in jobs will fail with the following error. ``` app/jobs/user_job.rb:2:in `<class:UserJob>': undefined method `enqueue_after_transaction_commit=' for class UserJob (NoMethodError) ``` I removed `active_record` hook to fix this. Active Record are onld used inside methods in ``EnqueueAfterTransactionCommit`. So I think it's safe to load the module without Active Record.
1 parent c653e26 commit ba61580

File tree

4 files changed

+41
-19
lines changed

4 files changed

+41
-19
lines changed

activejob/lib/active_job/enqueue_after_transaction_commit.rb

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,6 @@
22

33
module ActiveJob
44
module EnqueueAfterTransactionCommit # :nodoc:
5-
extend ActiveSupport::Concern
6-
7-
included do
8-
##
9-
# :singleton-method:
10-
#
11-
# Defines if enqueueing this job from inside an Active Record transaction
12-
# automatically defers the enqueue to after the transaction commits.
13-
#
14-
# It can be set on a per job basis:
15-
# - `:always` forces the job to be deferred.
16-
# - `:never` forces the job to be queued immediately.
17-
# - `:default` lets the queue adapter define the behavior (recommended).
18-
class_attribute :enqueue_after_transaction_commit, instance_accessor: false, instance_predicate: false, default: :never
19-
end
20-
215
private
226
def raw_enqueue
237
after_transaction = case self.class.enqueue_after_transaction_commit

activejob/lib/active_job/enqueuing.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,20 @@ def perform_all_later(*jobs)
4040
module Enqueuing
4141
extend ActiveSupport::Concern
4242

43+
included do
44+
##
45+
# :singleton-method:
46+
#
47+
# Defines if enqueueing this job from inside an Active Record transaction
48+
# automatically defers the enqueue to after the transaction commits.
49+
#
50+
# It can be set on a per job basis:
51+
# - `:always` forces the job to be deferred.
52+
# - `:never` forces the job to be queued immediately.
53+
# - `:default` lets the queue adapter define the behavior (recommended).
54+
class_attribute :enqueue_after_transaction_commit, instance_accessor: false, instance_predicate: false, default: :never
55+
end
56+
4357
# Includes the +perform_later+ method for job initialization.
4458
module ClassMethods
4559
# Push a job onto the queue. By default the arguments must be either String,

activejob/lib/active_job/railtie.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ class Railtie < Rails::Railtie # :nodoc:
2626
end
2727

2828
initializer "active_job.enqueue_after_transaction_commit" do |app|
29-
ActiveSupport.on_load(:active_record) do
30-
ActiveSupport.on_load(:active_job) do
31-
include EnqueueAfterTransactionCommit
29+
ActiveSupport.on_load(:active_job) do
30+
ActiveSupport.on_load(:active_record) do
31+
ActiveJob::Base.include EnqueueAfterTransactionCommit
3232

3333
if app.config.active_job.key?(:enqueue_after_transaction_commit)
3434
ActiveJob::Base.enqueue_after_transaction_commit = app.config.active_job.delete(:enqueue_after_transaction_commit)
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# frozen_string_literal: true
2+
3+
require "isolation/abstract_unit"
4+
5+
module ApplicationTests
6+
class ActiveJobRailtieTest < ActiveSupport::TestCase
7+
include ActiveSupport::Testing::Isolation
8+
9+
setup :build_app
10+
teardown :teardown_app
11+
12+
test "jobs can set 'enqueue_after_transaction_commit' when eager_load is true" do
13+
add_to_env_config "development", "config.eager_load = true"
14+
15+
app_file "app/jobs/foo_job.rb", <<-RUBY
16+
class FooJob < ActiveJob::Base
17+
self.enqueue_after_transaction_commit = :never
18+
end
19+
RUBY
20+
21+
assert_equal ":never", rails("runner", "p FooJob.enqueue_after_transaction_commit").strip
22+
end
23+
end
24+
end

0 commit comments

Comments
 (0)