activejob 5.2.4 → 6.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +103 -34
  3. data/MIT-LICENSE +1 -1
  4. data/README.md +17 -10
  5. data/lib/active_job.rb +2 -1
  6. data/lib/active_job/arguments.rb +40 -28
  7. data/lib/active_job/base.rb +3 -1
  8. data/lib/active_job/callbacks.rb +4 -1
  9. data/lib/active_job/core.rb +38 -21
  10. data/lib/active_job/enqueuing.rb +26 -5
  11. data/lib/active_job/exceptions.rb +40 -17
  12. data/lib/active_job/execution.rb +1 -1
  13. data/lib/active_job/gem_version.rb +3 -3
  14. data/lib/active_job/logging.rb +40 -9
  15. data/lib/active_job/queue_adapter.rb +2 -0
  16. data/lib/active_job/queue_adapters.rb +8 -10
  17. data/lib/active_job/queue_adapters/async_adapter.rb +1 -1
  18. data/lib/active_job/queue_adapters/backburner_adapter.rb +2 -2
  19. data/lib/active_job/queue_adapters/inline_adapter.rb +1 -1
  20. data/lib/active_job/queue_adapters/test_adapter.rb +22 -8
  21. data/lib/active_job/queue_name.rb +21 -1
  22. data/lib/active_job/railtie.rb +16 -1
  23. data/lib/active_job/serializers.rb +63 -0
  24. data/lib/active_job/serializers/date_serializer.rb +21 -0
  25. data/lib/active_job/serializers/date_time_serializer.rb +21 -0
  26. data/lib/active_job/serializers/duration_serializer.rb +24 -0
  27. data/lib/active_job/serializers/object_serializer.rb +54 -0
  28. data/lib/active_job/serializers/symbol_serializer.rb +21 -0
  29. data/lib/active_job/serializers/time_serializer.rb +21 -0
  30. data/lib/active_job/serializers/time_with_zone_serializer.rb +21 -0
  31. data/lib/active_job/test_helper.rb +278 -57
  32. data/lib/active_job/timezones.rb +13 -0
  33. data/lib/active_job/translation.rb +1 -1
  34. data/lib/rails/generators/job/job_generator.rb +4 -0
  35. metadata +19 -11
  36. data/lib/active_job/queue_adapters/qu_adapter.rb +0 -46
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a26d4f0fe4bf636102ed72545f971829362c4d0b290e6809fe45923c825cd47f
4
- data.tar.gz: 28210cd91beb4447e6923b0408c7c2c46d064a44aeb76c025fd29d768a90b790
3
+ metadata.gz: 7973ed6448fa8c345584aa106b5cbb2e7d4f0ec00dd9951ac9f620592e825dc9
4
+ data.tar.gz: '020897732f85bb7e354ebedda165f052444dcf22f14cc111e2e5f20bca70ce95'
5
5
  SHA512:
6
- metadata.gz: 03a8ea79abfc413272ca8c49808d731d17b3882d6dc4d228d124ef473c978043013037213f7219a317aafeb2730124092ddcda6aaa91e9b84fdf2b6735b4222b
7
- data.tar.gz: de3e6fda55f3a1131d09896f95afb82e703cada838d460354336272b3f09439b9a3c5f30ba71dfc7c7226b0e18f64ea0c9d3cd80e688fb1747ed5e2451af214b
6
+ metadata.gz: 3c35419aea4a165a892334a40912031468bc691effd8c88740f63a2c99cf83fdebc2a76c118c7b9a93f83ac9159ef81fca748fd42155690d058c3c76c7ac5e3b
7
+ data.tar.gz: 602ed0cd77b1e68a17314c134314f4fdb26fbc7fea831bfc581ec5b7da4b4ed87f4ed1142c7a43e6781b059e8df6fa5c2efb6854bb69db20aa2bbebc179615af
@@ -1,27 +1,56 @@
1
- ## Rails 5.2.4 (November 27, 2019) ##
1
+ ## Rails 6.0.0 (August 16, 2019) ##
2
+
3
+ * `assert_enqueued_with` and `assert_performed_with` can now test jobs with relative delay.
4
+
5
+ *Vlado Cingel*
6
+
7
+
8
+ ## Rails 6.0.0.rc2 (July 22, 2019) ##
2
9
 
3
10
  * No changes.
4
11
 
5
12
 
6
- ## Rails 5.2.3 (March 27, 2019) ##
13
+ ## Rails 6.0.0.rc1 (April 24, 2019) ##
14
+
15
+ * Use individual execution counters when calculating retry delay.
16
+
17
+ *Patrik Bóna*
18
+
19
+ * Make job argument assertions with `Time`, `ActiveSupport::TimeWithZone`, and `DateTime` work by dropping microseconds. Microsecond precision is lost during serialization.
20
+
21
+ *Gannon McGibbon*
22
+
23
+
24
+ ## Rails 6.0.0.beta3 (March 11, 2019) ##
7
25
 
8
26
  * No changes.
9
27
 
10
28
 
11
- ## Rails 5.2.2.1 (March 11, 2019) ##
29
+ ## Rails 6.0.0.beta2 (February 25, 2019) ##
12
30
 
13
31
  * No changes.
14
32
 
15
33
 
16
- ## Rails 5.2.2 (December 04, 2018) ##
34
+ ## Rails 6.0.0.beta1 (January 18, 2019) ##
35
+
36
+ * Return false instead of the job instance when `enqueue` is aborted.
37
+
38
+ This will be the behavior in Rails 6.1 but it can be controlled now with
39
+ `config.active_job.return_false_on_aborted_enqueue`.
17
40
 
18
- * Make sure `assert_enqueued_with()` & `assert_performed_with()` work reliably with hash arguments.
41
+ *Kir Shatrov*
19
42
 
20
- *Sharang Dashputre*
43
+ * Keep executions for each specific declaration
21
44
 
22
- * Restore `ActionController::Parameters` support to `ActiveJob::Arguments.serialize`.
45
+ Each `retry_on` declaration has now its own specific executions counter. Before it was
46
+ shared between all executions of a job.
23
47
 
24
- *Bernie Chiu*
48
+ *Alberto Almagro*
49
+
50
+ * Allow all assertion helpers that have a `only` and `except` keyword to accept
51
+ Procs.
52
+
53
+ *Edouard Chin*
25
54
 
26
55
  * Restore `HashWithIndifferentAccess` support to `ActiveJob::Arguments.deserialize`.
27
56
 
@@ -32,27 +61,64 @@
32
61
 
33
62
  *Alan Wu*
34
63
 
35
- * Increment execution count before deserialize arguments.
64
+ * Allow `assert_enqueued_with`/`assert_performed_with` methods to accept
65
+ a proc for the `args` argument. This is useful to check if only a subset of arguments
66
+ matches your expectations.
36
67
 
37
- Currently, the execution count increments after deserializes arguments.
38
- Therefore, if an error occurs with deserialize, it retries indefinitely.
68
+ *Edouard Chin*
39
69
 
40
- *Yuji Yaginuma*
70
+ * `ActionDispatch::IntegrationTest` includes `ActiveJob::TestHelper` module by default.
71
+
72
+ *Ricardo Díaz*
41
73
 
74
+ * Added `enqueue_retry.active_job`, `retry_stopped.active_job`, and `discard.active_job` hooks.
42
75
 
43
- ## Rails 5.2.1.1 (November 27, 2018) ##
76
+ *steves*
44
77
 
45
- * Do not deserialize GlobalID objects that were not generated by Active Job.
78
+ * Allow `assert_performed_with` to be called without a block.
46
79
 
47
- Trusting any GlobaID object when deserializing jobs can allow attackers to access
48
- information that should not be accessible to them.
80
+ *bogdanvlviv*
49
81
 
50
- Fix CVE-2018-16476.
82
+ * Execution of `assert_performed_jobs`, and `assert_no_performed_jobs`
83
+ without a block should respect passed `:except`, `:only`, and `:queue` options.
51
84
 
52
- *Rafael Mendonça França*
85
+ *bogdanvlviv*
53
86
 
87
+ * Allow `:queue` option to job assertions and helpers.
54
88
 
55
- ## Rails 5.2.1 (August 07, 2018) ##
89
+ *bogdanvlviv*
90
+
91
+ * Allow `perform_enqueued_jobs` to be called without a block.
92
+
93
+ Performs all of the jobs that have been enqueued up to this point in the test.
94
+
95
+ *Kevin Deisz*
96
+
97
+ * Move `enqueue`/`enqueue_at` notifications to an around callback.
98
+
99
+ Improves timing accuracy over the old after callback by including
100
+ time spent writing to the adapter's IO implementation.
101
+
102
+ *Zach Kemp*
103
+
104
+ * Allow call `assert_enqueued_with` with no block.
105
+
106
+ Example:
107
+ ```
108
+ def test_assert_enqueued_with
109
+ MyJob.perform_later(1,2,3)
110
+ assert_enqueued_with(job: MyJob, args: [1,2,3], queue: 'low')
111
+
112
+ MyJob.set(wait_until: Date.tomorrow.noon).perform_later
113
+ assert_enqueued_with(job: MyJob, at: Date.tomorrow.noon)
114
+ end
115
+ ```
116
+
117
+ *bogdanvlviv*
118
+
119
+ * Allow passing multiple exceptions to `retry_on`, and `discard_on`.
120
+
121
+ *George Claghorn*
56
122
 
57
123
  * Pass the error instance as the second parameter of block executed by `discard_on`.
58
124
 
@@ -60,26 +126,29 @@
60
126
 
61
127
  *Yuji Yaginuma*
62
128
 
63
- ## Rails 5.2.0 (April 09, 2018) ##
129
+ * Remove support for Qu gem.
64
130
 
65
- * Allow block to be passed to `ActiveJob::Base.discard_on` to allow custom handling of discard jobs.
131
+ Reasons are that the Qu gem wasn't compatible since Rails 5.1,
132
+ gem development was stopped in 2014 and maintainers have
133
+ confirmed its demise. See issue #32273
66
134
 
67
- Example:
135
+ *Alberto Almagro*
136
+
137
+ * Add support for timezones to Active Job.
138
+
139
+ Record what was the current timezone in effect when the job was
140
+ enqueued and then restore when the job is executed in same way
141
+ that the current locale is recorded and restored.
142
+
143
+ *Andrew White*
68
144
 
69
- class RemoteServiceJob < ActiveJob::Base
70
- discard_on(CustomAppException) do |job, exception|
71
- ExceptionNotifier.caught(exception)
72
- end
145
+ * Rails 6 requires Ruby 2.5.0 or newer.
73
146
 
74
- def perform(*args)
75
- # Might raise CustomAppException for something domain specific
76
- end
77
- end
147
+ *Jeremy Daer*, *Kasper Timm Hansen*
78
148
 
79
- *Aidan Haran*
149
+ * Add support to define custom argument serializers.
80
150
 
81
- * Support redis-rb 4.0.
151
+ *Evgenii Pecherkin*, *Rafael Mendonça França*
82
152
 
83
- *Jeremy Daer*
84
153
 
85
- Please check [5-1-stable](https://github.com/rails/rails/blob/5-1-stable/activejob/CHANGELOG.md) for previous changes.
154
+ Please check [5-2-stable](https://github.com/rails/rails/blob/5-2-stable/activejob/CHANGELOG.md) for previous changes.
@@ -1,4 +1,4 @@
1
- Copyright (c) 2014-2018 David Heinemeier Hansson
1
+ Copyright (c) 2014-2019 David Heinemeier Hansson
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
- # Active Job -- Make work happen later
1
+ # Active Job Make work happen later
2
2
 
3
3
  Active Job is a framework for declaring jobs and making them run on a variety
4
- of queueing backends. These jobs can be everything from regularly scheduled
4
+ of queuing backends. These jobs can be everything from regularly scheduled
5
5
  clean-ups, to billing charges, to mailings. Anything that can be chopped up into
6
6
  small units of work and run in parallel, really.
7
7
 
@@ -17,12 +17,13 @@ about API differences between Delayed Job and Resque. Picking your queuing
17
17
  backend becomes more of an operational concern, then. And you'll be able to
18
18
  switch between them without having to rewrite your jobs.
19
19
 
20
+ You can read more about Active Job in the [Active Job Basics](https://edgeguides.rubyonrails.org/active_job_basics.html) guide.
20
21
 
21
22
  ## Usage
22
23
 
23
- To learn how to use your preferred queueing backend see its adapter
24
+ To learn how to use your preferred queuing backend see its adapter
24
25
  documentation at
25
- [ActiveJob::QueueAdapters](http://api.rubyonrails.org/classes/ActiveJob/QueueAdapters.html).
26
+ [ActiveJob::QueueAdapters](https://api.rubyonrails.org/classes/ActiveJob/QueueAdapters.html).
26
27
 
27
28
  Declare a job like so:
28
29
 
@@ -39,7 +40,7 @@ end
39
40
  Enqueue a job like so:
40
41
 
41
42
  ```ruby
42
- MyJob.perform_later record # Enqueue a job to be performed as soon as the queueing system is free.
43
+ MyJob.perform_later record # Enqueue a job to be performed as soon as the queuing system is free.
43
44
  ```
44
45
 
45
46
  ```ruby
@@ -82,11 +83,17 @@ This works with any class that mixes in GlobalID::Identification, which
82
83
  by default has been mixed into Active Record classes.
83
84
 
84
85
 
85
- ## Supported queueing systems
86
+ ## Supported queuing systems
86
87
 
87
- Active Job has built-in adapters for multiple queueing backends (Sidekiq,
88
+ Active Job has built-in adapters for multiple queuing backends (Sidekiq,
88
89
  Resque, Delayed Job and others). To get an up-to-date list of the adapters
89
- see the API Documentation for [ActiveJob::QueueAdapters](http://api.rubyonrails.org/classes/ActiveJob/QueueAdapters.html).
90
+ see the API Documentation for [ActiveJob::QueueAdapters](https://api.rubyonrails.org/classes/ActiveJob/QueueAdapters.html).
91
+
92
+ **Please note:** We are not accepting pull requests for new adapters. We
93
+ encourage library authors to provide an ActiveJob adapter as part of
94
+ their gem, or as a stand-alone gem. For discussion about this see the
95
+ following PRs: [23311](https://github.com/rails/rails/issues/23311#issuecomment-176275718),
96
+ [21406](https://github.com/rails/rails/pull/21406#issuecomment-138813484), and [#32285](https://github.com/rails/rails/pull/32285).
90
97
 
91
98
  ## Auxiliary gems
92
99
 
@@ -102,7 +109,7 @@ The latest version of Active Job can be installed with RubyGems:
102
109
 
103
110
  Source code can be downloaded as part of the Rails project on GitHub:
104
111
 
105
- * https://github.com/rails/rails/tree/5-2-stable/activejob
112
+ * https://github.com/rails/rails/tree/master/activejob
106
113
 
107
114
  ## License
108
115
 
@@ -115,7 +122,7 @@ Active Job is released under the MIT license:
115
122
 
116
123
  API documentation is at:
117
124
 
118
- * http://api.rubyonrails.org
125
+ * https://api.rubyonrails.org
119
126
 
120
127
  Bug reports for the Ruby on Rails project can be filed here:
121
128
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  #--
4
- # Copyright (c) 2014-2018 David Heinemeier Hansson
4
+ # Copyright (c) 2014-2019 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
@@ -33,6 +33,7 @@ module ActiveJob
33
33
 
34
34
  autoload :Base
35
35
  autoload :QueueAdapters
36
+ autoload :Serializers
36
37
  autoload :ConfiguredJob
37
38
  autoload :TestCase
38
39
  autoload :TestHelper
@@ -14,29 +14,30 @@ module ActiveJob
14
14
  end
15
15
 
16
16
  # Raised when an unsupported argument type is set as a job argument. We
17
- # currently support NilClass, Integer, Fixnum, Float, String, TrueClass, FalseClass,
18
- # Bignum, BigDecimal, and objects that can be represented as GlobalIDs (ex: Active Record).
17
+ # currently support String, Integer, Float, NilClass, TrueClass, FalseClass,
18
+ # BigDecimal, Symbol, Date, Time, DateTime, ActiveSupport::TimeWithZone,
19
+ # ActiveSupport::Duration, Hash, ActiveSupport::HashWithIndifferentAccess,
20
+ # Array or GlobalID::Identification instances, although this can be extended
21
+ # by adding custom serializers.
19
22
  # Raised if you set the key for a Hash something else than a string or
20
23
  # a symbol. Also raised when trying to serialize an object which can't be
21
- # identified with a Global ID - such as an unpersisted Active Record model.
24
+ # identified with a GlobalID - such as an unpersisted Active Record model.
22
25
  class SerializationError < ArgumentError; end
23
26
 
24
27
  module Arguments
25
28
  extend self
26
- # :nodoc:
27
- TYPE_WHITELIST = [ NilClass, String, Integer, Float, BigDecimal, TrueClass, FalseClass ]
28
- TYPE_WHITELIST.push(Fixnum, Bignum) unless 1.class == Integer
29
-
30
- # Serializes a set of arguments. Whitelisted types are returned
31
- # as-is. Arrays/Hashes are serialized element by element.
32
- # All other types are serialized using GlobalID.
29
+ # Serializes a set of arguments. Intrinsic types that can safely be
30
+ # serialized without mutation are returned as-is. Arrays/Hashes are
31
+ # serialized element by element. All other types are serialized using
32
+ # GlobalID.
33
33
  def serialize(arguments)
34
34
  arguments.map { |argument| serialize_argument(argument) }
35
35
  end
36
36
 
37
- # Deserializes a set of arguments. Whitelisted types are returned
38
- # as-is. Arrays/Hashes are deserialized element by element.
39
- # All other types are deserialized using GlobalID.
37
+ # Deserializes a set of arguments. Intrinsic types that can safely be
38
+ # deserialized without mutation are returned as-is. Arrays/Hashes are
39
+ # deserialized element by element. All other types are deserialized using
40
+ # GlobalID.
40
41
  def deserialize(arguments)
41
42
  arguments.map { |argument| deserialize_argument(argument) }
42
43
  rescue
@@ -44,17 +45,30 @@ module ActiveJob
44
45
  end
45
46
 
46
47
  private
48
+
49
+ # :nodoc:
50
+ PERMITTED_TYPES = [ NilClass, String, Integer, Float, BigDecimal, TrueClass, FalseClass ]
51
+ # :nodoc:
52
+ GLOBALID_KEY = "_aj_globalid"
53
+ # :nodoc:
54
+ SYMBOL_KEYS_KEY = "_aj_symbol_keys"
47
55
  # :nodoc:
48
- GLOBALID_KEY = "_aj_globalid".freeze
56
+ WITH_INDIFFERENT_ACCESS_KEY = "_aj_hash_with_indifferent_access"
49
57
  # :nodoc:
50
- SYMBOL_KEYS_KEY = "_aj_symbol_keys".freeze
58
+ OBJECT_SERIALIZER_KEY = "_aj_serialized"
59
+
51
60
  # :nodoc:
52
- WITH_INDIFFERENT_ACCESS_KEY = "_aj_hash_with_indifferent_access".freeze
53
- private_constant :GLOBALID_KEY, :SYMBOL_KEYS_KEY, :WITH_INDIFFERENT_ACCESS_KEY
61
+ RESERVED_KEYS = [
62
+ GLOBALID_KEY, GLOBALID_KEY.to_sym,
63
+ SYMBOL_KEYS_KEY, SYMBOL_KEYS_KEY.to_sym,
64
+ OBJECT_SERIALIZER_KEY, OBJECT_SERIALIZER_KEY.to_sym,
65
+ WITH_INDIFFERENT_ACCESS_KEY, WITH_INDIFFERENT_ACCESS_KEY.to_sym,
66
+ ]
67
+ private_constant :PERMITTED_TYPES, :RESERVED_KEYS, :GLOBALID_KEY, :SYMBOL_KEYS_KEY, :WITH_INDIFFERENT_ACCESS_KEY
54
68
 
55
69
  def serialize_argument(argument)
56
70
  case argument
57
- when *TYPE_WHITELIST
71
+ when *PERMITTED_TYPES
58
72
  argument
59
73
  when GlobalID::Identification
60
74
  convert_to_global_id_hash(argument)
@@ -70,7 +84,7 @@ module ActiveJob
70
84
  when -> (arg) { arg.respond_to?(:permitted?) }
71
85
  serialize_indifferent_hash(argument.to_h)
72
86
  else
73
- raise SerializationError.new("Unsupported argument type: #{argument.class.name}")
87
+ Serializers.serialize(argument)
74
88
  end
75
89
  end
76
90
 
@@ -78,13 +92,15 @@ module ActiveJob
78
92
  case argument
79
93
  when String
80
94
  argument
81
- when *TYPE_WHITELIST
95
+ when *PERMITTED_TYPES
82
96
  argument
83
97
  when Array
84
98
  argument.map { |arg| deserialize_argument(arg) }
85
99
  when Hash
86
100
  if serialized_global_id?(argument)
87
101
  deserialize_global_id argument
102
+ elsif custom_serialized?(argument)
103
+ Serializers.deserialize(argument)
88
104
  else
89
105
  deserialize_hash(argument)
90
106
  end
@@ -101,6 +117,10 @@ module ActiveJob
101
117
  GlobalID::Locator.locate hash[GLOBALID_KEY]
102
118
  end
103
119
 
120
+ def custom_serialized?(hash)
121
+ hash.key?(OBJECT_SERIALIZER_KEY)
122
+ end
123
+
104
124
  def serialize_hash(argument)
105
125
  argument.each_with_object({}) do |(key, value), hash|
106
126
  hash[serialize_hash_key(key)] = serialize_argument(value)
@@ -117,14 +137,6 @@ module ActiveJob
117
137
  result
118
138
  end
119
139
 
120
- # :nodoc:
121
- RESERVED_KEYS = [
122
- GLOBALID_KEY, GLOBALID_KEY.to_sym,
123
- SYMBOL_KEYS_KEY, SYMBOL_KEYS_KEY.to_sym,
124
- WITH_INDIFFERENT_ACCESS_KEY, WITH_INDIFFERENT_ACCESS_KEY.to_sym,
125
- ]
126
- private_constant :RESERVED_KEYS
127
-
128
140
  def serialize_hash_key(key)
129
141
  case key
130
142
  when *RESERVED_KEYS
@@ -9,6 +9,7 @@ require "active_job/execution"
9
9
  require "active_job/callbacks"
10
10
  require "active_job/exceptions"
11
11
  require "active_job/logging"
12
+ require "active_job/timezones"
12
13
  require "active_job/translation"
13
14
 
14
15
  module ActiveJob #:nodoc:
@@ -39,7 +40,7 @@ module ActiveJob #:nodoc:
39
40
  # Records that are passed in are serialized/deserialized using Global
40
41
  # ID. More information can be found in Arguments.
41
42
  #
42
- # To enqueue a job to be performed as soon as the queueing system is free:
43
+ # To enqueue a job to be performed as soon as the queuing system is free:
43
44
  #
44
45
  # ProcessPhotoJob.perform_later(photo)
45
46
  #
@@ -67,6 +68,7 @@ module ActiveJob #:nodoc:
67
68
  include Callbacks
68
69
  include Exceptions
69
70
  include Logging
71
+ include Timezones
70
72
  include Translation
71
73
 
72
74
  ActiveSupport.run_load_hooks(:active_job, self)
@@ -29,6 +29,9 @@ module ActiveJob
29
29
  included do
30
30
  define_callbacks :perform
31
31
  define_callbacks :enqueue
32
+
33
+ class_attribute :return_false_on_aborted_enqueue, instance_accessor: false, instance_predicate: false
34
+ self.return_false_on_aborted_enqueue = false
32
35
  end
33
36
 
34
37
  # These methods will be included into any Active Job object, adding
@@ -130,7 +133,7 @@ module ActiveJob
130
133
  set_callback(:enqueue, :after, *filters, &blk)
131
134
  end
132
135
 
133
- # Defines a callback that will get called around the enqueueing
136
+ # Defines a callback that will get called around the enqueuing
134
137
  # of the job.
135
138
  #
136
139
  # class VideoProcessJob < ActiveJob::Base