activejob 7.0.8.7 → 7.2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +40 -229
  3. data/MIT-LICENSE +1 -1
  4. data/README.md +2 -2
  5. data/lib/active_job/arguments.rb +18 -32
  6. data/lib/active_job/base.rb +1 -1
  7. data/lib/active_job/callbacks.rb +3 -8
  8. data/lib/active_job/configured_job.rb +4 -0
  9. data/lib/active_job/core.rb +11 -6
  10. data/lib/active_job/deprecator.rb +7 -0
  11. data/lib/active_job/enqueue_after_transaction_commit.rb +28 -0
  12. data/lib/active_job/enqueuing.rb +71 -12
  13. data/lib/active_job/exceptions.rb +44 -7
  14. data/lib/active_job/execution.rb +5 -2
  15. data/lib/active_job/gem_version.rb +4 -4
  16. data/lib/active_job/instrumentation.rb +18 -10
  17. data/lib/active_job/log_subscriber.rb +80 -8
  18. data/lib/active_job/logging.rb +16 -2
  19. data/lib/active_job/queue_adapter.rb +18 -6
  20. data/lib/active_job/queue_adapters/abstract_adapter.rb +27 -0
  21. data/lib/active_job/queue_adapters/async_adapter.rb +3 -3
  22. data/lib/active_job/queue_adapters/backburner_adapter.rb +8 -4
  23. data/lib/active_job/queue_adapters/delayed_job_adapter.rb +10 -2
  24. data/lib/active_job/queue_adapters/inline_adapter.rb +6 -2
  25. data/lib/active_job/queue_adapters/queue_classic_adapter.rb +13 -5
  26. data/lib/active_job/queue_adapters/resque_adapter.rb +2 -2
  27. data/lib/active_job/queue_adapters/sidekiq_adapter.rb +43 -15
  28. data/lib/active_job/queue_adapters/sneakers_adapter.rb +2 -2
  29. data/lib/active_job/queue_adapters/sucker_punch_adapter.rb +4 -4
  30. data/lib/active_job/queue_adapters/test_adapter.rb +13 -5
  31. data/lib/active_job/queue_adapters.rb +9 -7
  32. data/lib/active_job/queue_priority.rb +18 -1
  33. data/lib/active_job/railtie.rb +38 -7
  34. data/lib/active_job/serializers/big_decimal_serializer.rb +22 -0
  35. data/lib/active_job/serializers/duration_serializer.rb +4 -2
  36. data/lib/active_job/serializers/object_serializer.rb +2 -0
  37. data/lib/active_job/serializers/time_with_zone_serializer.rb +11 -2
  38. data/lib/active_job/serializers.rb +7 -3
  39. data/lib/active_job/test_helper.rb +60 -19
  40. data/lib/active_job/version.rb +1 -1
  41. data/lib/active_job.rb +34 -4
  42. data/lib/rails/generators/job/USAGE +19 -0
  43. data/lib/rails/generators/job/job_generator.rb +6 -2
  44. data/lib/rails/generators/job/templates/job.rb.tt +1 -1
  45. metadata +12 -8
  46. data/lib/active_job/queue_adapters/que_adapter.rb +0 -61
@@ -34,13 +34,18 @@ module ActiveJob
34
34
  end
35
35
  end
36
36
 
37
- ActiveJob::Base.include(TestQueueAdapter)
37
+ ActiveSupport.on_load(:active_job) do
38
+ ActiveJob::Base.include(TestQueueAdapter)
39
+ end
38
40
 
39
41
  def before_setup # :nodoc:
40
- test_adapter = queue_adapter_for_test
41
-
42
+ queue_adapter_specific_to_this_test_class = queue_adapter_for_test
42
43
  queue_adapter_changed_jobs.each do |klass|
43
- klass.enable_test_adapter(test_adapter)
44
+ if queue_adapter_specific_to_this_test_class
45
+ klass.enable_test_adapter(queue_adapter_specific_to_this_test_class)
46
+ elsif klass._queue_adapter.nil?
47
+ klass.enable_test_adapter(ActiveJob::QueueAdapters::TestAdapter.new)
48
+ end
44
49
  end
45
50
 
46
51
  clear_enqueued_jobs
@@ -54,17 +59,11 @@ module ActiveJob
54
59
  queue_adapter_changed_jobs.each { |klass| klass.disable_test_adapter }
55
60
  end
56
61
 
57
- # Specifies the queue adapter to use with all Active Job test helpers.
58
- #
59
- # Returns an instance of the queue adapter and defaults to
60
- # ActiveJob::QueueAdapters::TestAdapter.
61
- #
62
- # Note: The adapter provided by this method must provide some additional
63
- # methods from those expected of a standard ActiveJob::QueueAdapter
64
- # in order to be used with the active job test helpers. Refer to
65
- # ActiveJob::QueueAdapters::TestAdapter.
62
+ # Returns a queue adapter instance to use with all Active Job test helpers.
63
+ # By default, returns an instance of ActiveJob::QueueAdapters::TestAdapter.
64
+ # Override this method to specify a different adapter. The adapter must
65
+ # implement the same interface as ActiveJob::QueueAdapters::TestAdapter.
66
66
  def queue_adapter_for_test
67
- ActiveJob::QueueAdapters::TestAdapter.new
68
67
  end
69
68
 
70
69
  # Asserts that the number of enqueued jobs matches the given number.
@@ -121,6 +120,8 @@ module ActiveJob
121
120
  # end
122
121
  # end
123
122
  def assert_enqueued_jobs(number, only: nil, except: nil, queue: nil, &block)
123
+ require_active_job_test_adapter!("assert_enqueued_jobs")
124
+
124
125
  if block_given?
125
126
  original_jobs = enqueued_jobs_with(only: only, except: except, queue: queue)
126
127
 
@@ -183,6 +184,8 @@ module ActiveJob
183
184
  #
184
185
  # assert_enqueued_jobs 0, &block
185
186
  def assert_no_enqueued_jobs(only: nil, except: nil, queue: nil, &block)
187
+ require_active_job_test_adapter!("assert_no_enqueued_jobs")
188
+
186
189
  assert_enqueued_jobs 0, only: only, except: except, queue: queue, &block
187
190
  end
188
191
 
@@ -273,6 +276,8 @@ module ActiveJob
273
276
  # end
274
277
  # end
275
278
  def assert_performed_jobs(number, only: nil, except: nil, queue: nil, &block)
279
+ require_active_job_test_adapter!("assert_performed_jobs")
280
+
276
281
  if block_given?
277
282
  original_count = performed_jobs.size
278
283
 
@@ -341,6 +346,8 @@ module ActiveJob
341
346
  #
342
347
  # assert_performed_jobs 0, &block
343
348
  def assert_no_performed_jobs(only: nil, except: nil, queue: nil, &block)
349
+ require_active_job_test_adapter!("assert_no_performed_jobs")
350
+
344
351
  assert_performed_jobs 0, only: only, except: except, queue: queue, &block
345
352
  end
346
353
 
@@ -354,6 +361,13 @@ module ActiveJob
354
361
  # assert_enqueued_with(at: Date.tomorrow.noon, queue: "my_queue")
355
362
  # end
356
363
  #
364
+ # For keyword arguments, specify them as a hash inside an array:
365
+ #
366
+ # def test_assert_enqueued_with_keyword_arguments
367
+ # MyJob.perform_later(arg1: 'value1', arg2: 'value2')
368
+ # assert_enqueued_with(job: MyJob, args: [{ arg1: 'value1', arg2: 'value2' }])
369
+ # end
370
+ #
357
371
  # The given arguments may also be specified as matcher procs that return a
358
372
  # boolean value indicating whether a job's attribute meets certain criteria.
359
373
  #
@@ -390,6 +404,8 @@ module ActiveJob
390
404
  # end
391
405
  # end
392
406
  def assert_enqueued_with(job: nil, args: nil, at: nil, queue: nil, priority: nil, &block)
407
+ require_active_job_test_adapter!("assert_enqueued_with")
408
+
393
409
  expected = { job: job, args: args, at: at, queue: queue, priority: priority }.compact
394
410
  expected_args = prepare_args_for_assertion(expected)
395
411
  potential_matches = []
@@ -492,6 +508,8 @@ module ActiveJob
492
508
  # end
493
509
  # end
494
510
  def assert_performed_with(job: nil, args: nil, at: nil, queue: nil, priority: nil, &block)
511
+ require_active_job_test_adapter!("assert_performed_with")
512
+
495
513
  expected = { job: job, args: args, at: at, queue: queue, priority: priority }.compact
496
514
  expected_args = prepare_args_for_assertion(expected)
497
515
  potential_matches = []
@@ -593,10 +611,19 @@ module ActiveJob
593
611
  # assert_performed_jobs 1
594
612
  # end
595
613
  #
596
- # If the +:at+ option is specified, then only run jobs enqueued to run
597
- # immediately or before the given time
614
+ # If the +:at+ option is specified, then only jobs that have been enqueued
615
+ # to run at or before the given time will be performed. This includes jobs
616
+ # that have been enqueued without a time.
617
+ #
618
+ # If queue_adapter_for_test is overridden to return a different adapter,
619
+ # +perform_enqueued_jobs+ will merely execute the block.
598
620
  def perform_enqueued_jobs(only: nil, except: nil, queue: nil, at: nil, &block)
599
- return flush_enqueued_jobs(only: only, except: except, queue: queue, at: at) unless block_given?
621
+ unless block_given?
622
+ require_active_job_test_adapter!("perform_enqueued_jobs (without a block)")
623
+ return flush_enqueued_jobs(only: only, except: except, queue: queue, at: at)
624
+ end
625
+
626
+ return _assert_nothing_raised_or_warn("perform_enqueued_jobs", &block) unless using_test_adapter?
600
627
 
601
628
  validate_option(only: only, except: except)
602
629
 
@@ -636,12 +663,22 @@ module ActiveJob
636
663
  end
637
664
 
638
665
  private
666
+ def require_active_job_test_adapter!(method)
667
+ unless using_test_adapter?
668
+ raise ArgumentError.new("#{method} requires the Active Job test adapter, you're using #{queue_adapter.class.name}.")
669
+ end
670
+ end
671
+
672
+ def using_test_adapter?
673
+ queue_adapter.is_a?(ActiveJob::QueueAdapters::TestAdapter)
674
+ end
675
+
639
676
  def clear_enqueued_jobs
640
- enqueued_jobs.clear
677
+ enqueued_jobs.clear if using_test_adapter?
641
678
  end
642
679
 
643
680
  def clear_performed_jobs
644
- performed_jobs.clear
681
+ performed_jobs.clear if using_test_adapter?
645
682
  end
646
683
 
647
684
  def jobs_with(jobs, only: nil, except: nil, queue: nil, at: nil)
@@ -694,6 +731,10 @@ module ActiveJob
694
731
 
695
732
  def prepare_args_for_assertion(args)
696
733
  args.dup.tap do |arguments|
734
+ if arguments[:queue].is_a?(Symbol)
735
+ arguments[:queue] = arguments[:queue].to_s
736
+ end
737
+
697
738
  if arguments[:at].acts_like?(:time)
698
739
  at_range = arguments[:at] - 1..arguments[:at] + 1
699
740
  arguments[:at] = ->(at) { at_range.cover?(at) }
@@ -3,7 +3,7 @@
3
3
  require_relative "gem_version"
4
4
 
5
5
  module ActiveJob
6
- # Returns the currently loaded version of Active Job as a <tt>Gem::Version</tt>.
6
+ # Returns the currently loaded version of Active Job as a +Gem::Version+.
7
7
  def self.version
8
8
  gem_version
9
9
  end
data/lib/active_job.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  #--
4
- # Copyright (c) 2014-2022 David Heinemeier Hansson
4
+ # Copyright (c) David Heinemeier Hansson
5
5
  #
6
6
  # Permission is hereby granted, free of charge, to any person obtaining
7
7
  # a copy of this software and associated documentation files (the
@@ -26,16 +26,46 @@
26
26
  require "active_support"
27
27
  require "active_support/rails"
28
28
  require "active_job/version"
29
+ require "active_job/deprecator"
29
30
  require "global_id"
30
31
 
32
+ # :markup: markdown
33
+ # :include: ../README.md
31
34
  module ActiveJob
32
35
  extend ActiveSupport::Autoload
33
36
 
34
37
  autoload :Base
35
38
  autoload :QueueAdapters
36
- autoload :Serializers
37
- autoload :ConfiguredJob
39
+ autoload :Arguments
40
+ autoload :DeserializationError, "active_job/arguments"
41
+ autoload :SerializationError, "active_job/arguments"
42
+ autoload :EnqueueAfterTransactionCommit
43
+
44
+ eager_autoload do
45
+ autoload :Serializers
46
+ autoload :ConfiguredJob
47
+ end
48
+
38
49
  autoload :TestCase
39
50
  autoload :TestHelper
40
- autoload :QueryTags
51
+
52
+ def self.use_big_decimal_serializer
53
+ ActiveJob.deprecator.warn <<-WARNING.squish
54
+ Rails.application.config.active_job.use_big_decimal_serializer is deprecated and will be removed in Rails 8.0.
55
+ WARNING
56
+ end
57
+
58
+ def self.use_big_decimal_serializer=(value)
59
+ ActiveJob.deprecator.warn <<-WARNING.squish
60
+ Rails.application.config.active_job.use_big_decimal_serializer is deprecated and will be removed in Rails 8.0.
61
+ WARNING
62
+ end
63
+
64
+ ##
65
+ # :singleton-method: verbose_enqueue_logs
66
+ #
67
+ # Specifies if the methods calling background job enqueue should be logged below
68
+ # their relevant enqueue log lines. Defaults to false.
69
+ singleton_class.attr_accessor :verbose_enqueue_logs
70
+ self.verbose_enqueue_logs = false
41
71
  end
@@ -0,0 +1,19 @@
1
+ Description:
2
+ Generates a new job. Pass the job name, either CamelCased or
3
+ under_scored, with or without the job postfix.
4
+
5
+ Examples:
6
+ `bin/rails generate job checkout`
7
+
8
+ Creates the following files:
9
+
10
+ Job: app/jobs/checkout_job.rb
11
+ Test: test/jobs/checkout_job_test.rb
12
+
13
+ `bin/rails generate job send_sms --queue=sms`
14
+
15
+ Creates a job and test with a custom sms queue.
16
+
17
+ `bin/rails generate job process_payment --parent=payment_job`
18
+
19
+ Creates a job and test with a `PaymentJob` parent class.
@@ -5,10 +5,10 @@ require "rails/generators/named_base"
5
5
  module Rails # :nodoc:
6
6
  module Generators # :nodoc:
7
7
  class JobGenerator < Rails::Generators::NamedBase # :nodoc:
8
- desc "This generator creates an active job file at app/jobs"
9
-
10
8
  class_option :queue, type: :string, default: "default", desc: "The queue name for the generated job"
11
9
 
10
+ class_option :parent, type: :string, default: "ApplicationJob", desc: "The parent class for the generated job"
11
+
12
12
  check_class_collision suffix: "Job"
13
13
 
14
14
  hook_for :test_framework
@@ -28,6 +28,10 @@ module Rails # :nodoc:
28
28
  end
29
29
 
30
30
  private
31
+ def parent_class_name
32
+ options[:parent]
33
+ end
34
+
31
35
  def file_name
32
36
  @_file_name ||= super.sub(/_job\z/i, "")
33
37
  end
@@ -1,5 +1,5 @@
1
1
  <% module_namespacing do -%>
2
- class <%= class_name %>Job < ApplicationJob
2
+ class <%= class_name %>Job < <%= parent_class_name.classify %>
3
3
  queue_as :<%= options[:queue] %>
4
4
 
5
5
  def perform(*args)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activejob
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.0.8.7
4
+ version: 7.2.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Heinemeier Hansson
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 7.0.8.7
19
+ version: 7.2.2.1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 7.0.8.7
26
+ version: 7.2.2.1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: globalid
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -53,6 +53,8 @@ files:
53
53
  - lib/active_job/callbacks.rb
54
54
  - lib/active_job/configured_job.rb
55
55
  - lib/active_job/core.rb
56
+ - lib/active_job/deprecator.rb
57
+ - lib/active_job/enqueue_after_transaction_commit.rb
56
58
  - lib/active_job/enqueuing.rb
57
59
  - lib/active_job/exceptions.rb
58
60
  - lib/active_job/execution.rb
@@ -62,11 +64,11 @@ files:
62
64
  - lib/active_job/logging.rb
63
65
  - lib/active_job/queue_adapter.rb
64
66
  - lib/active_job/queue_adapters.rb
67
+ - lib/active_job/queue_adapters/abstract_adapter.rb
65
68
  - lib/active_job/queue_adapters/async_adapter.rb
66
69
  - lib/active_job/queue_adapters/backburner_adapter.rb
67
70
  - lib/active_job/queue_adapters/delayed_job_adapter.rb
68
71
  - lib/active_job/queue_adapters/inline_adapter.rb
69
- - lib/active_job/queue_adapters/que_adapter.rb
70
72
  - lib/active_job/queue_adapters/queue_classic_adapter.rb
71
73
  - lib/active_job/queue_adapters/resque_adapter.rb
72
74
  - lib/active_job/queue_adapters/sidekiq_adapter.rb
@@ -77,6 +79,7 @@ files:
77
79
  - lib/active_job/queue_priority.rb
78
80
  - lib/active_job/railtie.rb
79
81
  - lib/active_job/serializers.rb
82
+ - lib/active_job/serializers/big_decimal_serializer.rb
80
83
  - lib/active_job/serializers/date_serializer.rb
81
84
  - lib/active_job/serializers/date_time_serializer.rb
82
85
  - lib/active_job/serializers/duration_serializer.rb
@@ -92,6 +95,7 @@ files:
92
95
  - lib/active_job/timezones.rb
93
96
  - lib/active_job/translation.rb
94
97
  - lib/active_job/version.rb
98
+ - lib/rails/generators/job/USAGE
95
99
  - lib/rails/generators/job/job_generator.rb
96
100
  - lib/rails/generators/job/templates/application_job.rb.tt
97
101
  - lib/rails/generators/job/templates/job.rb.tt
@@ -100,10 +104,10 @@ licenses:
100
104
  - MIT
101
105
  metadata:
102
106
  bug_tracker_uri: https://github.com/rails/rails/issues
103
- changelog_uri: https://github.com/rails/rails/blob/v7.0.8.7/activejob/CHANGELOG.md
104
- documentation_uri: https://api.rubyonrails.org/v7.0.8.7/
107
+ changelog_uri: https://github.com/rails/rails/blob/v7.2.2.1/activejob/CHANGELOG.md
108
+ documentation_uri: https://api.rubyonrails.org/v7.2.2.1/
105
109
  mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
106
- source_code_uri: https://github.com/rails/rails/tree/v7.0.8.7/activejob
110
+ source_code_uri: https://github.com/rails/rails/tree/v7.2.2.1/activejob
107
111
  rubygems_mfa_required: 'true'
108
112
  post_install_message:
109
113
  rdoc_options: []
@@ -113,7 +117,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
113
117
  requirements:
114
118
  - - ">="
115
119
  - !ruby/object:Gem::Version
116
- version: 2.7.0
120
+ version: 3.1.0
117
121
  required_rubygems_version: !ruby/object:Gem::Requirement
118
122
  requirements:
119
123
  - - ">="
@@ -1,61 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "que"
4
-
5
- module ActiveJob
6
- module QueueAdapters
7
- # == Que adapter for Active Job
8
- #
9
- # Que is a high-performance alternative to DelayedJob or QueueClassic that
10
- # improves the reliability of your application by protecting your jobs with
11
- # the same ACID guarantees as the rest of your data. Que is a queue for
12
- # Ruby and PostgreSQL that manages jobs using advisory locks.
13
- #
14
- # Read more about Que {here}[https://github.com/chanks/que].
15
- #
16
- # To use Que set the queue_adapter config to +:que+.
17
- #
18
- # Rails.application.config.active_job.queue_adapter = :que
19
- class QueAdapter
20
- def enqueue(job) # :nodoc:
21
- job_options = { priority: job.priority, queue: job.queue_name }
22
- que_job = nil
23
-
24
- if require_job_options_kwarg?
25
- que_job = JobWrapper.enqueue job.serialize, job_options: job_options
26
- else
27
- que_job = JobWrapper.enqueue job.serialize, **job_options
28
- end
29
-
30
- job.provider_job_id = que_job.attrs["job_id"]
31
- que_job
32
- end
33
-
34
- def enqueue_at(job, timestamp) # :nodoc:
35
- job_options = { priority: job.priority, queue: job.queue_name, run_at: Time.at(timestamp) }
36
- que_job = nil
37
-
38
- if require_job_options_kwarg?
39
- que_job = JobWrapper.enqueue job.serialize, job_options: job_options
40
- else
41
- que_job = JobWrapper.enqueue job.serialize, **job_options
42
- end
43
-
44
- job.provider_job_id = que_job.attrs["job_id"]
45
- que_job
46
- end
47
-
48
- private
49
- def require_job_options_kwarg?
50
- @require_job_options_kwarg ||=
51
- JobWrapper.method(:enqueue).parameters.any? { |ptype, pname| ptype == :key && pname == :job_options }
52
- end
53
-
54
- class JobWrapper < Que::Job # :nodoc:
55
- def run(job_data)
56
- Base.execute job_data
57
- end
58
- end
59
- end
60
- end
61
- end