rbs_rails 0.3.0 → 0.4.0
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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +3 -0
- data/Gemfile +3 -2
- data/README.md +1 -0
- data/Rakefile +10 -2
- data/Steepfile +1 -0
- data/assets/sig/active_record.rbs +1 -1
- data/assets/sig/generated/actionpack.rbs +697 -543
- data/assets/sig/generated/actionview.rbs +313 -213
- data/assets/sig/generated/activejob.rbs +1920 -0
- data/assets/sig/generated/activemodel.rbs +690 -615
- data/assets/sig/generated/activerecord.rbs +5521 -4942
- data/assets/sig/generated/activesupport.rbs +1613 -1207
- data/assets/sig/generated/railties.rbs +426 -386
- data/assets/sig/patches/README.md +4 -0
- data/assets/sig/patches/for_actionpack.rbs +74 -0
- data/assets/sig/patches/for_actionview.rbs +19 -0
- data/assets/sig/patches/for_activemodel.rbs +11 -0
- data/assets/sig/patches/for_activerecord.rbs +84 -0
- data/assets/sig/patches/for_activesupport.rbs +48 -0
- data/assets/sig/patches/for_railties.rbs +30 -0
- data/assets/sig/pg.rbs +5 -0
- data/assets/sig/que.rbs +4 -0
- data/assets/sig/queue_classic.rbs +4 -0
- data/assets/sig/rack.rbs +1 -0
- data/assets/sig/sidekiq.rbs +4 -0
- data/assets/sig/sneakers.rbs +4 -0
- data/assets/sig/sucker_punch.rbs +4 -0
- data/bin/add-type-params.rb +7 -0
- data/bin/generate_rbs_from_rails_source_code.rb +195 -0
- data/bin/postprocess.rb +15 -6
- data/bin/rbs +1 -1
- data/lib/rbs_rails/active_record.rb +40 -10
- data/lib/rbs_rails/version.rb +1 -1
- metadata +18 -3
@@ -0,0 +1,1920 @@
|
|
1
|
+
module ActiveJob
|
2
|
+
# Raised when an exception is raised during job arguments deserialization.
|
3
|
+
#
|
4
|
+
# Wraps the original exception raised as +cause+.
|
5
|
+
class DeserializationError < StandardError
|
6
|
+
def initialize: () -> untyped
|
7
|
+
end
|
8
|
+
|
9
|
+
# Raised when an unsupported argument type is set as a job argument. We
|
10
|
+
# currently support String, Integer, Float, NilClass, TrueClass, FalseClass,
|
11
|
+
# BigDecimal, Symbol, Date, Time, DateTime, ActiveSupport::TimeWithZone,
|
12
|
+
# ActiveSupport::Duration, Hash, ActiveSupport::HashWithIndifferentAccess,
|
13
|
+
# Array or GlobalID::Identification instances, although this can be extended
|
14
|
+
# by adding custom serializers.
|
15
|
+
# Raised if you set the key for a Hash something else than a string or
|
16
|
+
# a symbol. Also raised when trying to serialize an object which can't be
|
17
|
+
# identified with a GlobalID - such as an unpersisted Active Record model.
|
18
|
+
class SerializationError < ArgumentError
|
19
|
+
end
|
20
|
+
|
21
|
+
module Arguments
|
22
|
+
# Serializes a set of arguments. Intrinsic types that can safely be
|
23
|
+
# serialized without mutation are returned as-is. Arrays/Hashes are
|
24
|
+
# serialized element by element. All other types are serialized using
|
25
|
+
# GlobalID.
|
26
|
+
def serialize: (untyped arguments) -> untyped
|
27
|
+
|
28
|
+
# Deserializes a set of arguments. Intrinsic types that can safely be
|
29
|
+
# deserialized without mutation are returned as-is. Arrays/Hashes are
|
30
|
+
# deserialized element by element. All other types are deserialized using
|
31
|
+
# GlobalID.
|
32
|
+
def deserialize: (untyped arguments) -> untyped
|
33
|
+
|
34
|
+
# :nodoc:
|
35
|
+
PERMITTED_TYPES: ::Array[untyped]
|
36
|
+
|
37
|
+
# :nodoc:
|
38
|
+
GLOBALID_KEY: ::String
|
39
|
+
|
40
|
+
# :nodoc:
|
41
|
+
SYMBOL_KEYS_KEY: ::String
|
42
|
+
|
43
|
+
# :nodoc:
|
44
|
+
RUBY2_KEYWORDS_KEY: ::String
|
45
|
+
|
46
|
+
# :nodoc:
|
47
|
+
WITH_INDIFFERENT_ACCESS_KEY: ::String
|
48
|
+
|
49
|
+
# :nodoc:
|
50
|
+
OBJECT_SERIALIZER_KEY: ::String
|
51
|
+
|
52
|
+
# :nodoc:
|
53
|
+
RESERVED_KEYS: ::Array[untyped]
|
54
|
+
|
55
|
+
def self.ruby2_keywords_hash?: (untyped hash) -> untyped
|
56
|
+
|
57
|
+
def self.ruby2_keywords_hash?: (untyped hash) -> ::FalseClass
|
58
|
+
|
59
|
+
def self.ruby2_keywords_hash: (untyped hash) -> untyped
|
60
|
+
|
61
|
+
def self._ruby2_keywords_hash: (*untyped args) -> untyped
|
62
|
+
|
63
|
+
def serialize_argument: (untyped argument) -> untyped
|
64
|
+
|
65
|
+
def deserialize_argument: (untyped argument) -> untyped
|
66
|
+
|
67
|
+
def serialized_global_id?: (untyped hash) -> untyped
|
68
|
+
|
69
|
+
def deserialize_global_id: (untyped hash) -> untyped
|
70
|
+
|
71
|
+
def custom_serialized?: (untyped hash) -> untyped
|
72
|
+
|
73
|
+
def serialize_hash: (untyped argument) -> untyped
|
74
|
+
|
75
|
+
def deserialize_hash: (untyped serialized_hash) -> untyped
|
76
|
+
|
77
|
+
def serialize_hash_key: (untyped key) -> untyped
|
78
|
+
|
79
|
+
def serialize_indifferent_hash: (untyped indifferent_hash) -> untyped
|
80
|
+
|
81
|
+
def transform_symbol_keys: (untyped hash, untyped symbol_keys) -> untyped
|
82
|
+
|
83
|
+
def convert_to_global_id_hash: (untyped argument) -> untyped
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
module ActiveJob
|
88
|
+
# nodoc:
|
89
|
+
# = Active Job
|
90
|
+
#
|
91
|
+
# Active Job objects can be configured to work with different backend
|
92
|
+
# queuing frameworks. To specify a queue adapter to use:
|
93
|
+
#
|
94
|
+
# ActiveJob::Base.queue_adapter = :inline
|
95
|
+
#
|
96
|
+
# A list of supported adapters can be found in QueueAdapters.
|
97
|
+
#
|
98
|
+
# Active Job objects can be defined by creating a class that inherits
|
99
|
+
# from the ActiveJob::Base class. The only necessary method to
|
100
|
+
# implement is the "perform" method.
|
101
|
+
#
|
102
|
+
# To define an Active Job object:
|
103
|
+
#
|
104
|
+
# class ProcessPhotoJob < ActiveJob::Base
|
105
|
+
# def perform(photo)
|
106
|
+
# photo.watermark!('Rails')
|
107
|
+
# photo.rotate!(90.degrees)
|
108
|
+
# photo.resize_to_fit!(300, 300)
|
109
|
+
# photo.upload!
|
110
|
+
# end
|
111
|
+
# end
|
112
|
+
#
|
113
|
+
# Records that are passed in are serialized/deserialized using Global
|
114
|
+
# ID. More information can be found in Arguments.
|
115
|
+
#
|
116
|
+
# To enqueue a job to be performed as soon as the queuing system is free:
|
117
|
+
#
|
118
|
+
# ProcessPhotoJob.perform_later(photo)
|
119
|
+
#
|
120
|
+
# To enqueue a job to be processed at some point in the future:
|
121
|
+
#
|
122
|
+
# ProcessPhotoJob.set(wait_until: Date.tomorrow.noon).perform_later(photo)
|
123
|
+
#
|
124
|
+
# More information can be found in ActiveJob::Core::ClassMethods#set
|
125
|
+
#
|
126
|
+
# A job can also be processed immediately without sending to the queue:
|
127
|
+
#
|
128
|
+
# ProcessPhotoJob.perform_now(photo)
|
129
|
+
#
|
130
|
+
# == Exceptions
|
131
|
+
#
|
132
|
+
# * DeserializationError - Error class for deserialization errors.
|
133
|
+
# * SerializationError - Error class for serialization errors.
|
134
|
+
class Base
|
135
|
+
include Core
|
136
|
+
|
137
|
+
extend ::ActiveJob::Core::ClassMethods
|
138
|
+
|
139
|
+
include QueueAdapter
|
140
|
+
|
141
|
+
extend ::ActiveJob::QueueAdapter::ClassMethods
|
142
|
+
|
143
|
+
include QueueName
|
144
|
+
|
145
|
+
extend ::ActiveJob::QueueName::ClassMethods
|
146
|
+
|
147
|
+
include QueuePriority
|
148
|
+
|
149
|
+
extend ::ActiveJob::QueuePriority::ClassMethods
|
150
|
+
|
151
|
+
include Enqueuing
|
152
|
+
|
153
|
+
extend ::ActiveJob::Enqueuing::ClassMethods
|
154
|
+
|
155
|
+
include Execution
|
156
|
+
|
157
|
+
extend ::ActiveJob::Execution::ClassMethods
|
158
|
+
|
159
|
+
include Callbacks
|
160
|
+
|
161
|
+
extend ::ActiveJob::Callbacks::ClassMethods
|
162
|
+
|
163
|
+
include Exceptions
|
164
|
+
|
165
|
+
extend ::ActiveJob::Exceptions::ClassMethods
|
166
|
+
|
167
|
+
include Logging
|
168
|
+
|
169
|
+
include Timezones
|
170
|
+
|
171
|
+
include Translation
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
module ActiveJob
|
176
|
+
# = Active Job Callbacks
|
177
|
+
#
|
178
|
+
# Active Job provides hooks during the life cycle of a job. Callbacks allow you
|
179
|
+
# to trigger logic during this cycle. Available callbacks are:
|
180
|
+
#
|
181
|
+
# * <tt>before_enqueue</tt>
|
182
|
+
# * <tt>around_enqueue</tt>
|
183
|
+
# * <tt>after_enqueue</tt>
|
184
|
+
# * <tt>before_perform</tt>
|
185
|
+
# * <tt>around_perform</tt>
|
186
|
+
# * <tt>after_perform</tt>
|
187
|
+
#
|
188
|
+
# NOTE: Calling the same callback multiple times will overwrite previous callback definitions.
|
189
|
+
#
|
190
|
+
module Callbacks
|
191
|
+
extend ActiveSupport::Concern
|
192
|
+
|
193
|
+
include ActiveSupport::Callbacks
|
194
|
+
|
195
|
+
extend ::ActiveSupport::Callbacks::ClassMethods
|
196
|
+
|
197
|
+
extend ::ActiveSupport::Callbacks::ClassMethods
|
198
|
+
|
199
|
+
include ActiveSupport::Callbacks
|
200
|
+
|
201
|
+
# These methods will be included into any Active Job object, adding
|
202
|
+
# callbacks for +perform+ and +enqueue+ methods.
|
203
|
+
module ClassMethods
|
204
|
+
# Defines a callback that will get called right before the
|
205
|
+
# job's perform method is executed.
|
206
|
+
#
|
207
|
+
# class VideoProcessJob < ActiveJob::Base
|
208
|
+
# queue_as :default
|
209
|
+
#
|
210
|
+
# before_perform do |job|
|
211
|
+
# UserMailer.notify_video_started_processing(job.arguments.first)
|
212
|
+
# end
|
213
|
+
#
|
214
|
+
# def perform(video_id)
|
215
|
+
# Video.find(video_id).process
|
216
|
+
# end
|
217
|
+
# end
|
218
|
+
#
|
219
|
+
def before_perform: (*untyped filters) { () -> untyped } -> untyped
|
220
|
+
|
221
|
+
# Defines a callback that will get called right after the
|
222
|
+
# job's perform method has finished.
|
223
|
+
#
|
224
|
+
# class VideoProcessJob < ActiveJob::Base
|
225
|
+
# queue_as :default
|
226
|
+
#
|
227
|
+
# after_perform do |job|
|
228
|
+
# UserMailer.notify_video_processed(job.arguments.first)
|
229
|
+
# end
|
230
|
+
#
|
231
|
+
# def perform(video_id)
|
232
|
+
# Video.find(video_id).process
|
233
|
+
# end
|
234
|
+
# end
|
235
|
+
#
|
236
|
+
def after_perform: (*untyped filters) { () -> untyped } -> untyped
|
237
|
+
|
238
|
+
# Defines a callback that will get called around the job's perform method.
|
239
|
+
#
|
240
|
+
# class VideoProcessJob < ActiveJob::Base
|
241
|
+
# queue_as :default
|
242
|
+
#
|
243
|
+
# around_perform do |job, block|
|
244
|
+
# UserMailer.notify_video_started_processing(job.arguments.first)
|
245
|
+
# block.call
|
246
|
+
# UserMailer.notify_video_processed(job.arguments.first)
|
247
|
+
# end
|
248
|
+
#
|
249
|
+
# def perform(video_id)
|
250
|
+
# Video.find(video_id).process
|
251
|
+
# end
|
252
|
+
# end
|
253
|
+
#
|
254
|
+
def around_perform: (*untyped filters) { () -> untyped } -> untyped
|
255
|
+
|
256
|
+
# Defines a callback that will get called right before the
|
257
|
+
# job is enqueued.
|
258
|
+
#
|
259
|
+
# class VideoProcessJob < ActiveJob::Base
|
260
|
+
# queue_as :default
|
261
|
+
#
|
262
|
+
# before_enqueue do |job|
|
263
|
+
# $statsd.increment "enqueue-video-job.try"
|
264
|
+
# end
|
265
|
+
#
|
266
|
+
# def perform(video_id)
|
267
|
+
# Video.find(video_id).process
|
268
|
+
# end
|
269
|
+
# end
|
270
|
+
#
|
271
|
+
def before_enqueue: (*untyped filters) { () -> untyped } -> untyped
|
272
|
+
|
273
|
+
# Defines a callback that will get called right after the
|
274
|
+
# job is enqueued.
|
275
|
+
#
|
276
|
+
# class VideoProcessJob < ActiveJob::Base
|
277
|
+
# queue_as :default
|
278
|
+
#
|
279
|
+
# after_enqueue do |job|
|
280
|
+
# $statsd.increment "enqueue-video-job.success"
|
281
|
+
# end
|
282
|
+
#
|
283
|
+
# def perform(video_id)
|
284
|
+
# Video.find(video_id).process
|
285
|
+
# end
|
286
|
+
# end
|
287
|
+
#
|
288
|
+
def after_enqueue: (*untyped filters) { () -> untyped } -> untyped
|
289
|
+
|
290
|
+
# Defines a callback that will get called around the enqueuing
|
291
|
+
# of the job.
|
292
|
+
#
|
293
|
+
# class VideoProcessJob < ActiveJob::Base
|
294
|
+
# queue_as :default
|
295
|
+
#
|
296
|
+
# around_enqueue do |job, block|
|
297
|
+
# $statsd.time "video-job.process" do
|
298
|
+
# block.call
|
299
|
+
# end
|
300
|
+
# end
|
301
|
+
#
|
302
|
+
# def perform(video_id)
|
303
|
+
# Video.find(video_id).process
|
304
|
+
# end
|
305
|
+
# end
|
306
|
+
#
|
307
|
+
def around_enqueue: (*untyped filters) { () -> untyped } -> untyped
|
308
|
+
end
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
module ActiveJob
|
313
|
+
class ConfiguredJob
|
314
|
+
# nodoc:
|
315
|
+
def initialize: (untyped job_class, ?::Hash[untyped, untyped] options) -> untyped
|
316
|
+
|
317
|
+
def perform_now: (*untyped args) -> untyped
|
318
|
+
|
319
|
+
def perform_later: (*untyped args) -> untyped
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
323
|
+
module ActiveJob
|
324
|
+
# Provides general behavior that will be included into every Active Job
|
325
|
+
# object that inherits from ActiveJob::Base.
|
326
|
+
module Core
|
327
|
+
extend ActiveSupport::Concern
|
328
|
+
|
329
|
+
# Job arguments
|
330
|
+
attr_accessor arguments: untyped
|
331
|
+
|
332
|
+
attr_writer serialized_arguments: untyped
|
333
|
+
|
334
|
+
# Timestamp when the job should be performed
|
335
|
+
attr_accessor scheduled_at: untyped
|
336
|
+
|
337
|
+
# Job Identifier
|
338
|
+
attr_accessor job_id: untyped
|
339
|
+
|
340
|
+
# Queue in which the job will reside.
|
341
|
+
attr_writer queue_name: untyped
|
342
|
+
|
343
|
+
# Priority that the job will have (lower is more priority).
|
344
|
+
attr_writer priority: untyped
|
345
|
+
|
346
|
+
# ID optionally provided by adapter
|
347
|
+
attr_accessor provider_job_id: untyped
|
348
|
+
|
349
|
+
# Number of times this job has been executed (which increments on every retry, like after an exception).
|
350
|
+
attr_accessor executions: untyped
|
351
|
+
|
352
|
+
# Hash that contains the number of times this job handled errors for each specific retry_on declaration.
|
353
|
+
# Keys are the string representation of the exceptions listed in the retry_on declaration,
|
354
|
+
# while its associated value holds the number of executions where the corresponding retry_on
|
355
|
+
# declaration handled one of its listed exceptions.
|
356
|
+
attr_accessor exception_executions: untyped
|
357
|
+
|
358
|
+
# I18n.locale to be used during the job.
|
359
|
+
attr_accessor locale: untyped
|
360
|
+
|
361
|
+
# Timezone to be used during the job.
|
362
|
+
attr_accessor timezone: untyped
|
363
|
+
|
364
|
+
# Track when a job was enqueued
|
365
|
+
attr_accessor enqueued_at: untyped
|
366
|
+
|
367
|
+
# These methods will be included into any Active Job object, adding
|
368
|
+
# helpers for de/serialization and creation of job instances.
|
369
|
+
module ClassMethods
|
370
|
+
# Creates a new job instance from a hash created with +serialize+
|
371
|
+
def deserialize: (untyped job_data) -> untyped
|
372
|
+
|
373
|
+
# Creates a job preconfigured with the given options. You can call
|
374
|
+
# perform_later with the job arguments to enqueue the job with the
|
375
|
+
# preconfigured options
|
376
|
+
#
|
377
|
+
# ==== Options
|
378
|
+
# * <tt>:wait</tt> - Enqueues the job with the specified delay
|
379
|
+
# * <tt>:wait_until</tt> - Enqueues the job at the time specified
|
380
|
+
# * <tt>:queue</tt> - Enqueues the job on the specified queue
|
381
|
+
# * <tt>:priority</tt> - Enqueues the job with the specified priority
|
382
|
+
#
|
383
|
+
# ==== Examples
|
384
|
+
#
|
385
|
+
# VideoJob.set(queue: :some_queue).perform_later(Video.last)
|
386
|
+
# VideoJob.set(wait: 5.minutes).perform_later(Video.last)
|
387
|
+
# VideoJob.set(wait_until: Time.now.tomorrow).perform_later(Video.last)
|
388
|
+
# VideoJob.set(queue: :some_queue, wait: 5.minutes).perform_later(Video.last)
|
389
|
+
# VideoJob.set(queue: :some_queue, wait_until: Time.now.tomorrow).perform_later(Video.last)
|
390
|
+
# VideoJob.set(queue: :some_queue, wait: 5.minutes, priority: 10).perform_later(Video.last)
|
391
|
+
def set: (?::Hash[untyped, untyped] options) -> ConfiguredJob
|
392
|
+
end
|
393
|
+
|
394
|
+
# Creates a new job instance. Takes the arguments that will be
|
395
|
+
# passed to the perform method.
|
396
|
+
def initialize: (*untyped arguments) -> untyped
|
397
|
+
|
398
|
+
# Returns a hash with the job data that can safely be passed to the
|
399
|
+
# queuing adapter.
|
400
|
+
def serialize: () -> ::Hash[::String, untyped]
|
401
|
+
|
402
|
+
# Attaches the stored job data to the current instance. Receives a hash
|
403
|
+
# returned from +serialize+
|
404
|
+
#
|
405
|
+
# ==== Examples
|
406
|
+
#
|
407
|
+
# class DeliverWebhookJob < ActiveJob::Base
|
408
|
+
# attr_writer :attempt_number
|
409
|
+
#
|
410
|
+
# def attempt_number
|
411
|
+
# @attempt_number ||= 0
|
412
|
+
# end
|
413
|
+
#
|
414
|
+
# def serialize
|
415
|
+
# super.merge('attempt_number' => attempt_number + 1)
|
416
|
+
# end
|
417
|
+
#
|
418
|
+
# def deserialize(job_data)
|
419
|
+
# super
|
420
|
+
# self.attempt_number = job_data['attempt_number']
|
421
|
+
# end
|
422
|
+
#
|
423
|
+
# rescue_from(Timeout::Error) do |exception|
|
424
|
+
# raise exception if attempt_number > 5
|
425
|
+
# retry_job(wait: 10)
|
426
|
+
# end
|
427
|
+
# end
|
428
|
+
def deserialize: (untyped job_data) -> untyped
|
429
|
+
|
430
|
+
def serialize_arguments_if_needed: (untyped arguments) -> untyped
|
431
|
+
|
432
|
+
def deserialize_arguments_if_needed: () -> untyped
|
433
|
+
|
434
|
+
def serialize_arguments: (untyped arguments) -> untyped
|
435
|
+
|
436
|
+
def deserialize_arguments: (untyped serialized_args) -> untyped
|
437
|
+
|
438
|
+
def arguments_serialized?: () -> untyped
|
439
|
+
end
|
440
|
+
end
|
441
|
+
|
442
|
+
module ActiveJob
|
443
|
+
# Provides behavior for enqueuing jobs.
|
444
|
+
module Enqueuing
|
445
|
+
extend ActiveSupport::Concern
|
446
|
+
|
447
|
+
# Includes the +perform_later+ method for job initialization.
|
448
|
+
module ClassMethods
|
449
|
+
# Push a job onto the queue. By default the arguments must be either String,
|
450
|
+
# Integer, Float, NilClass, TrueClass, FalseClass, BigDecimal, Symbol, Date,
|
451
|
+
# Time, DateTime, ActiveSupport::TimeWithZone, ActiveSupport::Duration,
|
452
|
+
# Hash, ActiveSupport::HashWithIndifferentAccess, Array or
|
453
|
+
# GlobalID::Identification instances, although this can be extended by adding
|
454
|
+
# custom serializers.
|
455
|
+
#
|
456
|
+
# Returns an instance of the job class queued with arguments available in
|
457
|
+
# Job#arguments.
|
458
|
+
def perform_later: (*untyped args) -> untyped
|
459
|
+
|
460
|
+
def job_or_instantiate: (*untyped args) -> untyped
|
461
|
+
end
|
462
|
+
|
463
|
+
# Enqueues the job to be performed by the queue adapter.
|
464
|
+
#
|
465
|
+
# ==== Options
|
466
|
+
# * <tt>:wait</tt> - Enqueues the job with the specified delay
|
467
|
+
# * <tt>:wait_until</tt> - Enqueues the job at the time specified
|
468
|
+
# * <tt>:queue</tt> - Enqueues the job on the specified queue
|
469
|
+
# * <tt>:priority</tt> - Enqueues the job with the specified priority
|
470
|
+
#
|
471
|
+
# ==== Examples
|
472
|
+
#
|
473
|
+
# my_job_instance.enqueue
|
474
|
+
# my_job_instance.enqueue wait: 5.minutes
|
475
|
+
# my_job_instance.enqueue queue: :important
|
476
|
+
# my_job_instance.enqueue wait_until: Date.tomorrow.midnight
|
477
|
+
# my_job_instance.enqueue priority: 10
|
478
|
+
def enqueue: (?::Hash[untyped, untyped] options) -> untyped
|
479
|
+
end
|
480
|
+
end
|
481
|
+
|
482
|
+
module ActiveJob
|
483
|
+
# Provides behavior for retrying and discarding jobs on exceptions.
|
484
|
+
module Exceptions
|
485
|
+
extend ActiveSupport::Concern
|
486
|
+
|
487
|
+
module ClassMethods
|
488
|
+
# Catch the exception and reschedule job for re-execution after so many seconds, for a specific number of attempts.
|
489
|
+
# If the exception keeps getting raised beyond the specified number of attempts, the exception is allowed to
|
490
|
+
# bubble up to the underlying queuing system, which may have its own retry mechanism or place it in a
|
491
|
+
# holding queue for inspection.
|
492
|
+
#
|
493
|
+
# You can also pass a block that'll be invoked if the retry attempts fail for custom logic rather than letting
|
494
|
+
# the exception bubble up. This block is yielded with the job instance as the first and the error instance as the second parameter.
|
495
|
+
#
|
496
|
+
# ==== Options
|
497
|
+
# * <tt>:wait</tt> - Re-enqueues the job with a delay specified either in seconds (default: 3 seconds),
|
498
|
+
# as a computing proc that the number of executions so far as an argument, or as a symbol reference of
|
499
|
+
# <tt>:exponentially_longer</tt>, which applies the wait algorithm of <tt>(executions ** 4) + 2</tt>
|
500
|
+
# (first wait 3s, then 18s, then 83s, etc)
|
501
|
+
# * <tt>:attempts</tt> - Re-enqueues the job the specified number of times (default: 5 attempts)
|
502
|
+
# * <tt>:queue</tt> - Re-enqueues the job on a different queue
|
503
|
+
# * <tt>:priority</tt> - Re-enqueues the job with a different priority
|
504
|
+
#
|
505
|
+
# ==== Examples
|
506
|
+
#
|
507
|
+
# class RemoteServiceJob < ActiveJob::Base
|
508
|
+
# retry_on CustomAppException # defaults to 3s wait, 5 attempts
|
509
|
+
# retry_on AnotherCustomAppException, wait: ->(executions) { executions * 2 }
|
510
|
+
#
|
511
|
+
# retry_on ActiveRecord::Deadlocked, wait: 5.seconds, attempts: 3
|
512
|
+
# retry_on Net::OpenTimeout, Timeout::Error, wait: :exponentially_longer, attempts: 10 # retries at most 10 times for Net::OpenTimeout and Timeout::Error combined
|
513
|
+
# # To retry at most 10 times for each individual exception:
|
514
|
+
# # retry_on Net::OpenTimeout, wait: :exponentially_longer, attempts: 10
|
515
|
+
# # retry_on Timeout::Error, wait: :exponentially_longer, attempts: 10
|
516
|
+
#
|
517
|
+
# retry_on(YetAnotherCustomAppException) do |job, error|
|
518
|
+
# ExceptionNotifier.caught(error)
|
519
|
+
# end
|
520
|
+
#
|
521
|
+
# def perform(*args)
|
522
|
+
# # Might raise CustomAppException, AnotherCustomAppException, or YetAnotherCustomAppException for something domain specific
|
523
|
+
# # Might raise ActiveRecord::Deadlocked when a local db deadlock is detected
|
524
|
+
# # Might raise Net::OpenTimeout or Timeout::Error when the remote service is down
|
525
|
+
# end
|
526
|
+
# end
|
527
|
+
def retry_on: (*untyped exceptions, ?wait: untyped wait, ?attempts: ::Integer attempts, ?queue: untyped? queue, ?priority: untyped? priority) { (untyped, untyped) -> untyped } -> untyped
|
528
|
+
|
529
|
+
# Discard the job with no attempts to retry, if the exception is raised. This is useful when the subject of the job,
|
530
|
+
# like an Active Record, is no longer available, and the job is thus no longer relevant.
|
531
|
+
#
|
532
|
+
# You can also pass a block that'll be invoked. This block is yielded with the job instance as the first and the error instance as the second parameter.
|
533
|
+
#
|
534
|
+
# ==== Example
|
535
|
+
#
|
536
|
+
# class SearchIndexingJob < ActiveJob::Base
|
537
|
+
# discard_on ActiveJob::DeserializationError
|
538
|
+
# discard_on(CustomAppException) do |job, error|
|
539
|
+
# ExceptionNotifier.caught(error)
|
540
|
+
# end
|
541
|
+
#
|
542
|
+
# def perform(record)
|
543
|
+
# # Will raise ActiveJob::DeserializationError if the record can't be deserialized
|
544
|
+
# # Might raise CustomAppException for something domain specific
|
545
|
+
# end
|
546
|
+
# end
|
547
|
+
def discard_on: (*untyped exceptions) { (untyped, untyped) -> untyped } -> untyped
|
548
|
+
end
|
549
|
+
|
550
|
+
# Reschedules the job to be re-executed. This is useful in combination
|
551
|
+
# with the +rescue_from+ option. When you rescue an exception from your job
|
552
|
+
# you can ask Active Job to retry performing your job.
|
553
|
+
#
|
554
|
+
# ==== Options
|
555
|
+
# * <tt>:wait</tt> - Enqueues the job with the specified delay in seconds
|
556
|
+
# * <tt>:wait_until</tt> - Enqueues the job at the time specified
|
557
|
+
# * <tt>:queue</tt> - Enqueues the job on the specified queue
|
558
|
+
# * <tt>:priority</tt> - Enqueues the job with the specified priority
|
559
|
+
#
|
560
|
+
# ==== Examples
|
561
|
+
#
|
562
|
+
# class SiteScraperJob < ActiveJob::Base
|
563
|
+
# rescue_from(ErrorLoadingSite) do
|
564
|
+
# retry_job queue: :low_priority
|
565
|
+
# end
|
566
|
+
#
|
567
|
+
# def perform(*args)
|
568
|
+
# # raise ErrorLoadingSite if cannot scrape
|
569
|
+
# end
|
570
|
+
# end
|
571
|
+
def retry_job: (?::Hash[untyped, untyped] options) -> untyped
|
572
|
+
|
573
|
+
def determine_delay: (seconds_or_duration_or_algorithm: untyped seconds_or_duration_or_algorithm, executions: untyped executions) -> untyped
|
574
|
+
|
575
|
+
def instrument: (untyped name, ?error: untyped? error, ?wait: untyped? wait) { () -> untyped } -> untyped
|
576
|
+
|
577
|
+
def executions_for: (untyped exceptions) -> untyped
|
578
|
+
end
|
579
|
+
end
|
580
|
+
|
581
|
+
module ActiveJob
|
582
|
+
module Execution
|
583
|
+
extend ActiveSupport::Concern
|
584
|
+
|
585
|
+
include ActiveSupport::Rescuable
|
586
|
+
|
587
|
+
extend ::ActiveSupport::Rescuable::ClassMethods
|
588
|
+
|
589
|
+
# Includes methods for executing and performing jobs instantly.
|
590
|
+
module ClassMethods
|
591
|
+
# Performs the job immediately.
|
592
|
+
#
|
593
|
+
# MyJob.perform_now("mike")
|
594
|
+
#
|
595
|
+
def perform_now: (*untyped args) -> untyped
|
596
|
+
|
597
|
+
def execute: (untyped job_data) -> untyped
|
598
|
+
end
|
599
|
+
|
600
|
+
# Performs the job immediately. The job is not sent to the queuing adapter
|
601
|
+
# but directly executed by blocking the execution of others until it's finished.
|
602
|
+
#
|
603
|
+
# MyJob.new(*args).perform_now
|
604
|
+
def perform_now: () -> untyped
|
605
|
+
|
606
|
+
def perform: () -> untyped
|
607
|
+
end
|
608
|
+
end
|
609
|
+
|
610
|
+
module ActiveJob
|
611
|
+
# Returns the version of the currently loaded Active Job as a <tt>Gem::Version</tt>
|
612
|
+
def self.gem_version: () -> Gem::Version
|
613
|
+
|
614
|
+
module VERSION
|
615
|
+
MAJOR: ::Integer
|
616
|
+
|
617
|
+
MINOR: ::Integer
|
618
|
+
|
619
|
+
TINY: ::Integer
|
620
|
+
|
621
|
+
PRE: ::String
|
622
|
+
|
623
|
+
STRING: untyped
|
624
|
+
end
|
625
|
+
end
|
626
|
+
|
627
|
+
module ActiveJob
|
628
|
+
module Logging
|
629
|
+
# nodoc:
|
630
|
+
extend ActiveSupport::Concern
|
631
|
+
|
632
|
+
def tag_logger: (*untyped tags) { () -> untyped } -> untyped
|
633
|
+
|
634
|
+
def logger_tagged_by_active_job?: () -> untyped
|
635
|
+
|
636
|
+
class LogSubscriber < ActiveSupport::LogSubscriber
|
637
|
+
# nodoc:
|
638
|
+
def enqueue: (untyped event) -> untyped
|
639
|
+
|
640
|
+
def enqueue_at: (untyped event) -> untyped
|
641
|
+
|
642
|
+
def perform_start: (untyped event) -> untyped
|
643
|
+
|
644
|
+
def perform: (untyped event) -> untyped
|
645
|
+
|
646
|
+
def enqueue_retry: (untyped event) -> untyped
|
647
|
+
|
648
|
+
def retry_stopped: (untyped event) -> untyped
|
649
|
+
|
650
|
+
def discard: (untyped event) -> untyped
|
651
|
+
|
652
|
+
def queue_name: (untyped event) -> untyped
|
653
|
+
|
654
|
+
def args_info: (untyped job) -> untyped
|
655
|
+
|
656
|
+
def format: (untyped arg) -> untyped
|
657
|
+
|
658
|
+
def scheduled_at: (untyped event) -> untyped
|
659
|
+
|
660
|
+
def logger: () -> untyped
|
661
|
+
end
|
662
|
+
end
|
663
|
+
end
|
664
|
+
|
665
|
+
module ActiveJob
|
666
|
+
module QueueAdapter
|
667
|
+
# The <tt>ActiveJob::QueueAdapter</tt> module is used to load the
|
668
|
+
# correct adapter. The default queue adapter is the +:async+ queue.
|
669
|
+
# nodoc:
|
670
|
+
extend ActiveSupport::Concern
|
671
|
+
|
672
|
+
# Includes the setter method for changing the active queue adapter.
|
673
|
+
module ClassMethods
|
674
|
+
# Returns the backend queue provider. The default queue adapter
|
675
|
+
# is the +:async+ queue. See QueueAdapters for more information.
|
676
|
+
def queue_adapter: () -> untyped
|
677
|
+
|
678
|
+
# Returns string denoting the name of the configured queue adapter.
|
679
|
+
# By default returns +"async"+.
|
680
|
+
def queue_adapter_name: () -> untyped
|
681
|
+
|
682
|
+
# Specify the backend queue provider. The default queue adapter
|
683
|
+
# is the +:async+ queue. See QueueAdapters for more
|
684
|
+
# information.
|
685
|
+
def queue_adapter=: (untyped name_or_adapter) -> untyped
|
686
|
+
|
687
|
+
def assign_adapter: (untyped adapter_name, untyped queue_adapter) -> untyped
|
688
|
+
|
689
|
+
QUEUE_ADAPTER_METHODS: untyped
|
690
|
+
|
691
|
+
def queue_adapter?: (untyped object) -> untyped
|
692
|
+
end
|
693
|
+
end
|
694
|
+
end
|
695
|
+
|
696
|
+
module ActiveJob
|
697
|
+
module QueueAdapters
|
698
|
+
# == Active Job Async adapter
|
699
|
+
#
|
700
|
+
# The Async adapter runs jobs with an in-process thread pool.
|
701
|
+
#
|
702
|
+
# This is the default queue adapter. It's well-suited for dev/test since
|
703
|
+
# it doesn't need an external infrastructure, but it's a poor fit for
|
704
|
+
# production since it drops pending jobs on restart.
|
705
|
+
#
|
706
|
+
# To use this adapter, set queue adapter to +:async+:
|
707
|
+
#
|
708
|
+
# config.active_job.queue_adapter = :async
|
709
|
+
#
|
710
|
+
# To configure the adapter's thread pool, instantiate the adapter and
|
711
|
+
# pass your own config:
|
712
|
+
#
|
713
|
+
# config.active_job.queue_adapter = ActiveJob::QueueAdapters::AsyncAdapter.new \
|
714
|
+
# min_threads: 1,
|
715
|
+
# max_threads: 2 * Concurrent.processor_count,
|
716
|
+
# idletime: 600.seconds
|
717
|
+
#
|
718
|
+
# The adapter uses a {Concurrent Ruby}[https://github.com/ruby-concurrency/concurrent-ruby] thread pool to schedule and execute
|
719
|
+
# jobs. Since jobs share a single thread pool, long-running jobs will block
|
720
|
+
# short-lived jobs. Fine for dev/test; bad for production.
|
721
|
+
class AsyncAdapter
|
722
|
+
# See {Concurrent::ThreadPoolExecutor}[https://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/ThreadPoolExecutor.html] for executor options.
|
723
|
+
def initialize: (**untyped executor_options) -> untyped
|
724
|
+
|
725
|
+
def enqueue: (untyped job) -> untyped
|
726
|
+
|
727
|
+
def enqueue_at: (untyped job, untyped timestamp) -> untyped
|
728
|
+
|
729
|
+
def shutdown: (?wait: bool wait) -> untyped
|
730
|
+
|
731
|
+
def immediate=: (untyped immediate) -> untyped
|
732
|
+
|
733
|
+
class JobWrapper
|
734
|
+
# Note that we don't actually need to serialize the jobs since we're
|
735
|
+
# performing them in-process, but we do so anyway for parity with other
|
736
|
+
# adapters and deployment environments. Otherwise, serialization bugs
|
737
|
+
# may creep in undetected.
|
738
|
+
# nodoc:
|
739
|
+
def initialize: (untyped job) -> untyped
|
740
|
+
|
741
|
+
def perform: () -> untyped
|
742
|
+
end
|
743
|
+
|
744
|
+
class Scheduler
|
745
|
+
# nodoc:
|
746
|
+
DEFAULT_EXECUTOR_OPTIONS: untyped
|
747
|
+
|
748
|
+
attr_accessor immediate: untyped
|
749
|
+
|
750
|
+
def initialize: (**untyped options) -> untyped
|
751
|
+
|
752
|
+
def enqueue: (untyped job, queue_name: untyped queue_name) -> untyped
|
753
|
+
|
754
|
+
def enqueue_at: (untyped job, untyped timestamp, queue_name: untyped queue_name) -> untyped
|
755
|
+
|
756
|
+
def shutdown: (?wait: bool wait) -> untyped
|
757
|
+
|
758
|
+
def executor: () -> untyped
|
759
|
+
end
|
760
|
+
end
|
761
|
+
end
|
762
|
+
end
|
763
|
+
|
764
|
+
module ActiveJob
|
765
|
+
module QueueAdapters
|
766
|
+
# == Backburner adapter for Active Job
|
767
|
+
#
|
768
|
+
# Backburner is a beanstalkd-powered job queue that can handle a very
|
769
|
+
# high volume of jobs. You create background jobs and place them on
|
770
|
+
# multiple work queues to be processed later. Read more about
|
771
|
+
# Backburner {here}[https://github.com/nesquena/backburner].
|
772
|
+
#
|
773
|
+
# To use Backburner set the queue_adapter config to +:backburner+.
|
774
|
+
#
|
775
|
+
# Rails.application.config.active_job.queue_adapter = :backburner
|
776
|
+
class BackburnerAdapter
|
777
|
+
def enqueue: (untyped job) -> untyped
|
778
|
+
|
779
|
+
def enqueue_at: (untyped job, untyped timestamp) -> untyped
|
780
|
+
|
781
|
+
class JobWrapper
|
782
|
+
def self.perform: (untyped job_data) -> untyped
|
783
|
+
end
|
784
|
+
end
|
785
|
+
end
|
786
|
+
end
|
787
|
+
|
788
|
+
module ActiveJob
|
789
|
+
module QueueAdapters
|
790
|
+
# == Delayed Job adapter for Active Job
|
791
|
+
#
|
792
|
+
# Delayed::Job (or DJ) encapsulates the common pattern of asynchronously
|
793
|
+
# executing longer tasks in the background. Although DJ can have many
|
794
|
+
# storage backends, one of the most used is based on Active Record.
|
795
|
+
# Read more about Delayed Job {here}[https://github.com/collectiveidea/delayed_job].
|
796
|
+
#
|
797
|
+
# To use Delayed Job, set the queue_adapter config to +:delayed_job+.
|
798
|
+
#
|
799
|
+
# Rails.application.config.active_job.queue_adapter = :delayed_job
|
800
|
+
class DelayedJobAdapter
|
801
|
+
def enqueue: (untyped job) -> untyped
|
802
|
+
|
803
|
+
def enqueue_at: (untyped job, untyped timestamp) -> untyped
|
804
|
+
|
805
|
+
class JobWrapper
|
806
|
+
# nodoc:
|
807
|
+
attr_accessor job_data: untyped
|
808
|
+
|
809
|
+
def initialize: (untyped job_data) -> untyped
|
810
|
+
|
811
|
+
def display_name: () -> ::String
|
812
|
+
|
813
|
+
def perform: () -> untyped
|
814
|
+
end
|
815
|
+
end
|
816
|
+
end
|
817
|
+
end
|
818
|
+
|
819
|
+
module ActiveJob
|
820
|
+
module QueueAdapters
|
821
|
+
# == Active Job Inline adapter
|
822
|
+
#
|
823
|
+
# When enqueuing jobs with the Inline adapter the job will be executed
|
824
|
+
# immediately.
|
825
|
+
#
|
826
|
+
# To use the Inline set the queue_adapter config to +:inline+.
|
827
|
+
#
|
828
|
+
# Rails.application.config.active_job.queue_adapter = :inline
|
829
|
+
class InlineAdapter
|
830
|
+
def enqueue: (untyped job) -> untyped
|
831
|
+
|
832
|
+
def enqueue_at: () -> untyped
|
833
|
+
end
|
834
|
+
end
|
835
|
+
end
|
836
|
+
|
837
|
+
module ActiveJob
|
838
|
+
module QueueAdapters
|
839
|
+
# == Que adapter for Active Job
|
840
|
+
#
|
841
|
+
# Que is a high-performance alternative to DelayedJob or QueueClassic that
|
842
|
+
# improves the reliability of your application by protecting your jobs with
|
843
|
+
# the same ACID guarantees as the rest of your data. Que is a queue for
|
844
|
+
# Ruby and PostgreSQL that manages jobs using advisory locks.
|
845
|
+
#
|
846
|
+
# Read more about Que {here}[https://github.com/chanks/que].
|
847
|
+
#
|
848
|
+
# To use Que set the queue_adapter config to +:que+.
|
849
|
+
#
|
850
|
+
# Rails.application.config.active_job.queue_adapter = :que
|
851
|
+
class QueAdapter
|
852
|
+
def enqueue: (untyped job) -> untyped
|
853
|
+
|
854
|
+
def enqueue_at: (untyped job, untyped timestamp) -> untyped
|
855
|
+
|
856
|
+
class JobWrapper < Que::Job
|
857
|
+
# nodoc:
|
858
|
+
def run: (untyped job_data) -> untyped
|
859
|
+
end
|
860
|
+
end
|
861
|
+
end
|
862
|
+
end
|
863
|
+
|
864
|
+
module ActiveJob
|
865
|
+
module QueueAdapters
|
866
|
+
# == queue_classic adapter for Active Job
|
867
|
+
#
|
868
|
+
# queue_classic provides a simple interface to a PostgreSQL-backed message
|
869
|
+
# queue. queue_classic specializes in concurrent locking and minimizing
|
870
|
+
# database load while providing a simple, intuitive developer experience.
|
871
|
+
# queue_classic assumes that you are already using PostgreSQL in your
|
872
|
+
# production environment and that adding another dependency (e.g. redis,
|
873
|
+
# beanstalkd, 0mq) is undesirable.
|
874
|
+
#
|
875
|
+
# Read more about queue_classic {here}[https://github.com/QueueClassic/queue_classic].
|
876
|
+
#
|
877
|
+
# To use queue_classic set the queue_adapter config to +:queue_classic+.
|
878
|
+
#
|
879
|
+
# Rails.application.config.active_job.queue_adapter = :queue_classic
|
880
|
+
class QueueClassicAdapter
|
881
|
+
def enqueue: (untyped job) -> untyped
|
882
|
+
|
883
|
+
def enqueue_at: (untyped job, untyped timestamp) -> untyped
|
884
|
+
|
885
|
+
# Builds a <tt>QC::Queue</tt> object to schedule jobs on.
|
886
|
+
#
|
887
|
+
# If you have a custom <tt>QC::Queue</tt> subclass you'll need to subclass
|
888
|
+
# <tt>ActiveJob::QueueAdapters::QueueClassicAdapter</tt> and override the
|
889
|
+
# <tt>build_queue</tt> method.
|
890
|
+
def build_queue: (untyped queue_name) -> QC::Queue
|
891
|
+
|
892
|
+
class JobWrapper
|
893
|
+
def self.perform: (untyped job_data) -> untyped
|
894
|
+
end
|
895
|
+
end
|
896
|
+
end
|
897
|
+
end
|
898
|
+
|
899
|
+
module ActiveJob
|
900
|
+
module QueueAdapters
|
901
|
+
# == Resque adapter for Active Job
|
902
|
+
#
|
903
|
+
# Resque (pronounced like "rescue") is a Redis-backed library for creating
|
904
|
+
# background jobs, placing those jobs on multiple queues, and processing
|
905
|
+
# them later.
|
906
|
+
#
|
907
|
+
# Read more about Resque {here}[https://github.com/resque/resque].
|
908
|
+
#
|
909
|
+
# To use Resque set the queue_adapter config to +:resque+.
|
910
|
+
#
|
911
|
+
# Rails.application.config.active_job.queue_adapter = :resque
|
912
|
+
class ResqueAdapter
|
913
|
+
def enqueue: (untyped job) -> untyped
|
914
|
+
|
915
|
+
def enqueue_at: (untyped job, untyped timestamp) -> untyped
|
916
|
+
|
917
|
+
class JobWrapper
|
918
|
+
def self.perform: (untyped job_data) -> untyped
|
919
|
+
end
|
920
|
+
end
|
921
|
+
end
|
922
|
+
end
|
923
|
+
|
924
|
+
module ActiveJob
|
925
|
+
module QueueAdapters
|
926
|
+
# == Sidekiq adapter for Active Job
|
927
|
+
#
|
928
|
+
# Simple, efficient background processing for Ruby. Sidekiq uses threads to
|
929
|
+
# handle many jobs at the same time in the same process. It does not
|
930
|
+
# require Rails but will integrate tightly with it to make background
|
931
|
+
# processing dead simple.
|
932
|
+
#
|
933
|
+
# Read more about Sidekiq {here}[http://sidekiq.org].
|
934
|
+
#
|
935
|
+
# To use Sidekiq set the queue_adapter config to +:sidekiq+.
|
936
|
+
#
|
937
|
+
# Rails.application.config.active_job.queue_adapter = :sidekiq
|
938
|
+
class SidekiqAdapter
|
939
|
+
def enqueue: (untyped job) -> untyped
|
940
|
+
|
941
|
+
def enqueue_at: (untyped job, untyped timestamp) -> untyped
|
942
|
+
|
943
|
+
class JobWrapper
|
944
|
+
# nodoc:
|
945
|
+
include Sidekiq::Worker
|
946
|
+
|
947
|
+
def perform: (untyped job_data) -> untyped
|
948
|
+
end
|
949
|
+
end
|
950
|
+
end
|
951
|
+
end
|
952
|
+
|
953
|
+
module ActiveJob
|
954
|
+
module QueueAdapters
|
955
|
+
# == Sneakers adapter for Active Job
|
956
|
+
#
|
957
|
+
# A high-performance RabbitMQ background processing framework for Ruby.
|
958
|
+
# Sneakers is being used in production for both I/O and CPU intensive
|
959
|
+
# workloads, and have achieved the goals of high-performance and
|
960
|
+
# 0-maintenance, as designed.
|
961
|
+
#
|
962
|
+
# Read more about Sneakers {here}[https://github.com/jondot/sneakers].
|
963
|
+
#
|
964
|
+
# To use Sneakers set the queue_adapter config to +:sneakers+.
|
965
|
+
#
|
966
|
+
# Rails.application.config.active_job.queue_adapter = :sneakers
|
967
|
+
class SneakersAdapter
|
968
|
+
def initialize: () -> untyped
|
969
|
+
|
970
|
+
def enqueue: (untyped job) -> untyped
|
971
|
+
|
972
|
+
def enqueue_at: (untyped job, untyped timestamp) -> untyped
|
973
|
+
|
974
|
+
class JobWrapper
|
975
|
+
# nodoc:
|
976
|
+
include Sneakers::Worker
|
977
|
+
|
978
|
+
def work: (untyped msg) -> untyped
|
979
|
+
end
|
980
|
+
end
|
981
|
+
end
|
982
|
+
end
|
983
|
+
|
984
|
+
module ActiveJob
|
985
|
+
module QueueAdapters
|
986
|
+
# == Sucker Punch adapter for Active Job
|
987
|
+
#
|
988
|
+
# Sucker Punch is a single-process Ruby asynchronous processing library.
|
989
|
+
# This reduces the cost of hosting on a service like Heroku along
|
990
|
+
# with the memory footprint of having to maintain additional jobs if
|
991
|
+
# hosting on a dedicated server. All queues can run within a
|
992
|
+
# single application (eg. Rails, Sinatra, etc.) process.
|
993
|
+
#
|
994
|
+
# Read more about Sucker Punch {here}[https://github.com/brandonhilkert/sucker_punch].
|
995
|
+
#
|
996
|
+
# To use Sucker Punch set the queue_adapter config to +:sucker_punch+.
|
997
|
+
#
|
998
|
+
# Rails.application.config.active_job.queue_adapter = :sucker_punch
|
999
|
+
class SuckerPunchAdapter
|
1000
|
+
def enqueue: (untyped job) -> untyped
|
1001
|
+
|
1002
|
+
def enqueue_at: (untyped job, untyped timestamp) -> untyped
|
1003
|
+
|
1004
|
+
class JobWrapper
|
1005
|
+
# nodoc:
|
1006
|
+
include SuckerPunch::Job
|
1007
|
+
|
1008
|
+
def perform: (untyped job_data) -> untyped
|
1009
|
+
end
|
1010
|
+
end
|
1011
|
+
end
|
1012
|
+
end
|
1013
|
+
|
1014
|
+
module ActiveJob
|
1015
|
+
module QueueAdapters
|
1016
|
+
# == Test adapter for Active Job
|
1017
|
+
#
|
1018
|
+
# The test adapter should be used only in testing. Along with
|
1019
|
+
# <tt>ActiveJob::TestCase</tt> and <tt>ActiveJob::TestHelper</tt>
|
1020
|
+
# it makes a great tool to test your Rails application.
|
1021
|
+
#
|
1022
|
+
# To use the test adapter set queue_adapter config to +:test+.
|
1023
|
+
#
|
1024
|
+
# Rails.application.config.active_job.queue_adapter = :test
|
1025
|
+
class TestAdapter
|
1026
|
+
attr_accessor perform_enqueued_jobs: untyped
|
1027
|
+
|
1028
|
+
attr_accessor perform_enqueued_at_jobs: untyped
|
1029
|
+
|
1030
|
+
attr_accessor filter: untyped
|
1031
|
+
|
1032
|
+
attr_accessor reject: untyped
|
1033
|
+
|
1034
|
+
attr_accessor queue: untyped
|
1035
|
+
|
1036
|
+
attr_writer enqueued_jobs: untyped
|
1037
|
+
|
1038
|
+
attr_writer performed_jobs: untyped
|
1039
|
+
|
1040
|
+
# Provides a store of all the enqueued jobs with the TestAdapter so you can check them.
|
1041
|
+
def enqueued_jobs: () -> untyped
|
1042
|
+
|
1043
|
+
# Provides a store of all the performed jobs with the TestAdapter so you can check them.
|
1044
|
+
def performed_jobs: () -> untyped
|
1045
|
+
|
1046
|
+
def enqueue: (untyped job) -> untyped
|
1047
|
+
|
1048
|
+
def enqueue_at: (untyped job, untyped timestamp) -> untyped
|
1049
|
+
|
1050
|
+
def job_to_hash: (untyped job, ?::Hash[untyped, untyped] extras) -> untyped
|
1051
|
+
|
1052
|
+
def perform_or_enqueue: (untyped perform, untyped job, untyped job_data) -> untyped
|
1053
|
+
|
1054
|
+
def filtered?: (untyped job) -> untyped
|
1055
|
+
|
1056
|
+
def filtered_queue?: (untyped job) -> untyped
|
1057
|
+
|
1058
|
+
def filtered_job_class?: (untyped job) -> untyped
|
1059
|
+
|
1060
|
+
def filter_as_proc: (untyped filter) -> untyped
|
1061
|
+
end
|
1062
|
+
end
|
1063
|
+
end
|
1064
|
+
|
1065
|
+
module ActiveJob
|
1066
|
+
# == Active Job adapters
|
1067
|
+
#
|
1068
|
+
# Active Job has adapters for the following queuing backends:
|
1069
|
+
#
|
1070
|
+
# * {Backburner}[https://github.com/nesquena/backburner]
|
1071
|
+
# * {Delayed Job}[https://github.com/collectiveidea/delayed_job]
|
1072
|
+
# * {Que}[https://github.com/chanks/que]
|
1073
|
+
# * {queue_classic}[https://github.com/QueueClassic/queue_classic]
|
1074
|
+
# * {Resque}[https://github.com/resque/resque]
|
1075
|
+
# * {Sidekiq}[https://sidekiq.org]
|
1076
|
+
# * {Sneakers}[https://github.com/jondot/sneakers]
|
1077
|
+
# * {Sucker Punch}[https://github.com/brandonhilkert/sucker_punch]
|
1078
|
+
# * {Active Job Async Job}[https://api.rubyonrails.org/classes/ActiveJob/QueueAdapters/AsyncAdapter.html]
|
1079
|
+
# * {Active Job Inline}[https://api.rubyonrails.org/classes/ActiveJob/QueueAdapters/InlineAdapter.html]
|
1080
|
+
# * Please Note: We are not accepting pull requests for new adapters. See the {README}[link:files/activejob/README_md.html] for more details.
|
1081
|
+
#
|
1082
|
+
# === Backends Features
|
1083
|
+
#
|
1084
|
+
# | | Async | Queues | Delayed | Priorities | Timeout | Retries |
|
1085
|
+
# |-------------------|-------|--------|------------|------------|---------|---------|
|
1086
|
+
# | Backburner | Yes | Yes | Yes | Yes | Job | Global |
|
1087
|
+
# | Delayed Job | Yes | Yes | Yes | Job | Global | Global |
|
1088
|
+
# | Que | Yes | Yes | Yes | Job | No | Job |
|
1089
|
+
# | queue_classic | Yes | Yes | Yes* | No | No | No |
|
1090
|
+
# | Resque | Yes | Yes | Yes (Gem) | Queue | Global | Yes |
|
1091
|
+
# | Sidekiq | Yes | Yes | Yes | Queue | No | Job |
|
1092
|
+
# | Sneakers | Yes | Yes | No | Queue | Queue | No |
|
1093
|
+
# | Sucker Punch | Yes | Yes | Yes | No | No | No |
|
1094
|
+
# | Active Job Async | Yes | Yes | Yes | No | No | No |
|
1095
|
+
# | Active Job Inline | No | Yes | N/A | N/A | N/A | N/A |
|
1096
|
+
#
|
1097
|
+
# ==== Async
|
1098
|
+
#
|
1099
|
+
# Yes: The Queue Adapter has the ability to run the job in a non-blocking manner.
|
1100
|
+
# It either runs on a separate or forked process, or on a different thread.
|
1101
|
+
#
|
1102
|
+
# No: The job is run in the same process.
|
1103
|
+
#
|
1104
|
+
# ==== Queues
|
1105
|
+
#
|
1106
|
+
# Yes: Jobs may set which queue they are run in with queue_as or by using the set
|
1107
|
+
# method.
|
1108
|
+
#
|
1109
|
+
# ==== Delayed
|
1110
|
+
#
|
1111
|
+
# Yes: The adapter will run the job in the future through perform_later.
|
1112
|
+
#
|
1113
|
+
# (Gem): An additional gem is required to use perform_later with this adapter.
|
1114
|
+
#
|
1115
|
+
# No: The adapter will run jobs at the next opportunity and cannot use perform_later.
|
1116
|
+
#
|
1117
|
+
# N/A: The adapter does not support queuing.
|
1118
|
+
#
|
1119
|
+
# NOTE:
|
1120
|
+
# queue_classic supports job scheduling since version 3.1.
|
1121
|
+
# For older versions you can use the queue_classic-later gem.
|
1122
|
+
#
|
1123
|
+
# ==== Priorities
|
1124
|
+
#
|
1125
|
+
# The order in which jobs are processed can be configured differently depending
|
1126
|
+
# on the adapter.
|
1127
|
+
#
|
1128
|
+
# Job: Any class inheriting from the adapter may set the priority on the job
|
1129
|
+
# object relative to other jobs.
|
1130
|
+
#
|
1131
|
+
# Queue: The adapter can set the priority for job queues, when setting a queue
|
1132
|
+
# with Active Job this will be respected.
|
1133
|
+
#
|
1134
|
+
# Yes: Allows the priority to be set on the job object, at the queue level or
|
1135
|
+
# as default configuration option.
|
1136
|
+
#
|
1137
|
+
# No: Does not allow the priority of jobs to be configured.
|
1138
|
+
#
|
1139
|
+
# N/A: The adapter does not support queuing, and therefore sorting them.
|
1140
|
+
#
|
1141
|
+
# ==== Timeout
|
1142
|
+
#
|
1143
|
+
# When a job will stop after the allotted time.
|
1144
|
+
#
|
1145
|
+
# Job: The timeout can be set for each instance of the job class.
|
1146
|
+
#
|
1147
|
+
# Queue: The timeout is set for all jobs on the queue.
|
1148
|
+
#
|
1149
|
+
# Global: The adapter is configured that all jobs have a maximum run time.
|
1150
|
+
#
|
1151
|
+
# N/A: This adapter does not run in a separate process, and therefore timeout
|
1152
|
+
# is unsupported.
|
1153
|
+
#
|
1154
|
+
# ==== Retries
|
1155
|
+
#
|
1156
|
+
# Job: The number of retries can be set per instance of the job class.
|
1157
|
+
#
|
1158
|
+
# Yes: The Number of retries can be configured globally, for each instance or
|
1159
|
+
# on the queue. This adapter may also present failed instances of the job class
|
1160
|
+
# that can be restarted.
|
1161
|
+
#
|
1162
|
+
# Global: The adapter has a global number of retries.
|
1163
|
+
#
|
1164
|
+
# N/A: The adapter does not run in a separate process, and therefore doesn't
|
1165
|
+
# support retries.
|
1166
|
+
#
|
1167
|
+
# === Async and Inline Queue Adapters
|
1168
|
+
#
|
1169
|
+
# Active Job has two built-in queue adapters intended for development and
|
1170
|
+
# testing: +:async+ and +:inline+.
|
1171
|
+
module QueueAdapters
|
1172
|
+
extend ActiveSupport::Autoload
|
1173
|
+
|
1174
|
+
ADAPTER: ::String
|
1175
|
+
|
1176
|
+
# Returns adapter for specified name.
|
1177
|
+
#
|
1178
|
+
# ActiveJob::QueueAdapters.lookup(:sidekiq)
|
1179
|
+
# # => ActiveJob::QueueAdapters::SidekiqAdapter
|
1180
|
+
def self.lookup: (untyped name) -> untyped
|
1181
|
+
end
|
1182
|
+
end
|
1183
|
+
|
1184
|
+
module ActiveJob
|
1185
|
+
module QueueName
|
1186
|
+
extend ActiveSupport::Concern
|
1187
|
+
|
1188
|
+
# Includes the ability to override the default queue name and prefix.
|
1189
|
+
module ClassMethods
|
1190
|
+
# Specifies the name of the queue to process the job on.
|
1191
|
+
#
|
1192
|
+
# class PublishToFeedJob < ActiveJob::Base
|
1193
|
+
# queue_as :feeds
|
1194
|
+
#
|
1195
|
+
# def perform(post)
|
1196
|
+
# post.to_feed!
|
1197
|
+
# end
|
1198
|
+
# end
|
1199
|
+
#
|
1200
|
+
# Can be given a block that will evaluate in the context of the job
|
1201
|
+
# allowing +self.arguments+ to be accessed so that a dynamic queue name
|
1202
|
+
# can be applied:
|
1203
|
+
#
|
1204
|
+
# class PublishToFeedJob < ApplicationJob
|
1205
|
+
# queue_as do
|
1206
|
+
# post = self.arguments.first
|
1207
|
+
#
|
1208
|
+
# if post.paid?
|
1209
|
+
# :paid_feeds
|
1210
|
+
# else
|
1211
|
+
# :feeds
|
1212
|
+
# end
|
1213
|
+
# end
|
1214
|
+
#
|
1215
|
+
# def perform(post)
|
1216
|
+
# post.to_feed!
|
1217
|
+
# end
|
1218
|
+
# end
|
1219
|
+
def queue_as: (?untyped? part_name) { () -> untyped } -> untyped
|
1220
|
+
|
1221
|
+
def queue_name_from_part: (untyped part_name) -> untyped
|
1222
|
+
end
|
1223
|
+
|
1224
|
+
# Returns the name of the queue the job will be run on.
|
1225
|
+
def queue_name: () -> untyped
|
1226
|
+
end
|
1227
|
+
end
|
1228
|
+
|
1229
|
+
module ActiveJob
|
1230
|
+
module QueuePriority
|
1231
|
+
extend ActiveSupport::Concern
|
1232
|
+
|
1233
|
+
# Includes the ability to override the default queue priority.
|
1234
|
+
module ClassMethods
|
1235
|
+
# Specifies the priority of the queue to create the job with.
|
1236
|
+
#
|
1237
|
+
# class PublishToFeedJob < ActiveJob::Base
|
1238
|
+
# queue_with_priority 50
|
1239
|
+
#
|
1240
|
+
# def perform(post)
|
1241
|
+
# post.to_feed!
|
1242
|
+
# end
|
1243
|
+
# end
|
1244
|
+
#
|
1245
|
+
# Specify either an argument or a block.
|
1246
|
+
def queue_with_priority: (?untyped? priority) { () -> untyped } -> untyped
|
1247
|
+
end
|
1248
|
+
|
1249
|
+
# Returns the priority that the job will be created with
|
1250
|
+
def priority: () -> untyped
|
1251
|
+
end
|
1252
|
+
end
|
1253
|
+
|
1254
|
+
module ActiveJob
|
1255
|
+
class Railtie < Rails::Railtie
|
1256
|
+
include ActiveJob::TestHelper
|
1257
|
+
end
|
1258
|
+
end
|
1259
|
+
|
1260
|
+
module ActiveJob
|
1261
|
+
module Serializers
|
1262
|
+
class DateSerializer < ObjectSerializer
|
1263
|
+
# :nodoc:
|
1264
|
+
def serialize: (untyped date) -> untyped
|
1265
|
+
|
1266
|
+
def deserialize: (untyped hash) -> untyped
|
1267
|
+
|
1268
|
+
def klass: () -> untyped
|
1269
|
+
end
|
1270
|
+
end
|
1271
|
+
end
|
1272
|
+
|
1273
|
+
module ActiveJob
|
1274
|
+
module Serializers
|
1275
|
+
class DateTimeSerializer < ObjectSerializer
|
1276
|
+
# :nodoc:
|
1277
|
+
def serialize: (untyped time) -> untyped
|
1278
|
+
|
1279
|
+
def deserialize: (untyped hash) -> untyped
|
1280
|
+
|
1281
|
+
def klass: () -> untyped
|
1282
|
+
end
|
1283
|
+
end
|
1284
|
+
end
|
1285
|
+
|
1286
|
+
module ActiveJob
|
1287
|
+
module Serializers
|
1288
|
+
class DurationSerializer < ObjectSerializer
|
1289
|
+
# :nodoc:
|
1290
|
+
def serialize: (untyped duration) -> untyped
|
1291
|
+
|
1292
|
+
def deserialize: (untyped hash) -> untyped
|
1293
|
+
|
1294
|
+
def klass: () -> untyped
|
1295
|
+
end
|
1296
|
+
end
|
1297
|
+
end
|
1298
|
+
|
1299
|
+
module ActiveJob
|
1300
|
+
module Serializers
|
1301
|
+
# Base class for serializing and deserializing custom objects.
|
1302
|
+
#
|
1303
|
+
# Example:
|
1304
|
+
#
|
1305
|
+
# class MoneySerializer < ActiveJob::Serializers::ObjectSerializer
|
1306
|
+
# def serialize(money)
|
1307
|
+
# super("amount" => money.amount, "currency" => money.currency)
|
1308
|
+
# end
|
1309
|
+
#
|
1310
|
+
# def deserialize(hash)
|
1311
|
+
# Money.new(hash["amount"], hash["currency"])
|
1312
|
+
# end
|
1313
|
+
#
|
1314
|
+
# private
|
1315
|
+
#
|
1316
|
+
# def klass
|
1317
|
+
# Money
|
1318
|
+
# end
|
1319
|
+
# end
|
1320
|
+
class ObjectSerializer
|
1321
|
+
include Singleton
|
1322
|
+
|
1323
|
+
# Determines if an argument should be serialized by a serializer.
|
1324
|
+
def serialize?: (untyped argument) -> untyped
|
1325
|
+
|
1326
|
+
# Serializes an argument to a JSON primitive type.
|
1327
|
+
def serialize: (untyped hash) -> untyped
|
1328
|
+
|
1329
|
+
# Deserializes an argument from a JSON primitive type.
|
1330
|
+
def deserialize: (untyped _argument) -> untyped
|
1331
|
+
|
1332
|
+
def klass: () -> untyped
|
1333
|
+
end
|
1334
|
+
end
|
1335
|
+
end
|
1336
|
+
|
1337
|
+
module ActiveJob
|
1338
|
+
module Serializers
|
1339
|
+
class SymbolSerializer < ObjectSerializer
|
1340
|
+
# :nodoc:
|
1341
|
+
def serialize: (untyped argument) -> untyped
|
1342
|
+
|
1343
|
+
def deserialize: (untyped argument) -> untyped
|
1344
|
+
|
1345
|
+
def klass: () -> untyped
|
1346
|
+
end
|
1347
|
+
end
|
1348
|
+
end
|
1349
|
+
|
1350
|
+
module ActiveJob
|
1351
|
+
module Serializers
|
1352
|
+
class TimeSerializer < ObjectSerializer
|
1353
|
+
# :nodoc:
|
1354
|
+
def serialize: (untyped time) -> untyped
|
1355
|
+
|
1356
|
+
def deserialize: (untyped hash) -> untyped
|
1357
|
+
|
1358
|
+
def klass: () -> untyped
|
1359
|
+
end
|
1360
|
+
end
|
1361
|
+
end
|
1362
|
+
|
1363
|
+
module ActiveJob
|
1364
|
+
module Serializers
|
1365
|
+
class TimeWithZoneSerializer < ObjectSerializer
|
1366
|
+
# :nodoc:
|
1367
|
+
def serialize: (untyped time) -> untyped
|
1368
|
+
|
1369
|
+
def deserialize: (untyped hash) -> untyped
|
1370
|
+
|
1371
|
+
def klass: () -> untyped
|
1372
|
+
end
|
1373
|
+
end
|
1374
|
+
end
|
1375
|
+
|
1376
|
+
module ActiveJob
|
1377
|
+
module Serializers
|
1378
|
+
# The <tt>ActiveJob::Serializers</tt> module is used to store a list of known serializers
|
1379
|
+
# and to add new ones. It also has helpers to serialize/deserialize objects.
|
1380
|
+
# :nodoc:
|
1381
|
+
extend ActiveSupport::Autoload
|
1382
|
+
|
1383
|
+
# Returns serialized representative of the passed object.
|
1384
|
+
# Will look up through all known serializers.
|
1385
|
+
# Raises <tt>ActiveJob::SerializationError</tt> if it can't find a proper serializer.
|
1386
|
+
def self.serialize: (untyped argument) -> untyped
|
1387
|
+
|
1388
|
+
# Returns deserialized object.
|
1389
|
+
# Will look up through all known serializers.
|
1390
|
+
# If no serializer found will raise <tt>ArgumentError</tt>.
|
1391
|
+
def self.deserialize: (untyped argument) -> untyped
|
1392
|
+
|
1393
|
+
# Returns list of known serializers.
|
1394
|
+
def self.serializers: () -> untyped
|
1395
|
+
|
1396
|
+
# Adds new serializers to a list of known serializers.
|
1397
|
+
def self.add_serializers: (*untyped new_serializers) -> untyped
|
1398
|
+
end
|
1399
|
+
end
|
1400
|
+
|
1401
|
+
module ActiveJob
|
1402
|
+
class TestCase < ActiveSupport::TestCase
|
1403
|
+
include ActiveJob::TestHelper
|
1404
|
+
end
|
1405
|
+
end
|
1406
|
+
|
1407
|
+
module ActiveJob
|
1408
|
+
# Provides helper methods for testing Active Job
|
1409
|
+
module TestHelper
|
1410
|
+
module TestQueueAdapter
|
1411
|
+
extend ActiveSupport::Concern
|
1412
|
+
|
1413
|
+
module ClassMethods
|
1414
|
+
def queue_adapter: () -> untyped
|
1415
|
+
|
1416
|
+
def disable_test_adapter: () -> untyped
|
1417
|
+
|
1418
|
+
def enable_test_adapter: (untyped test_adapter) -> untyped
|
1419
|
+
end
|
1420
|
+
end
|
1421
|
+
|
1422
|
+
def before_setup: () -> untyped
|
1423
|
+
|
1424
|
+
def after_teardown: () -> untyped
|
1425
|
+
|
1426
|
+
# Specifies the queue adapter to use with all Active Job test helpers.
|
1427
|
+
#
|
1428
|
+
# Returns an instance of the queue adapter and defaults to
|
1429
|
+
# <tt>ActiveJob::QueueAdapters::TestAdapter</tt>.
|
1430
|
+
#
|
1431
|
+
# Note: The adapter provided by this method must provide some additional
|
1432
|
+
# methods from those expected of a standard <tt>ActiveJob::QueueAdapter</tt>
|
1433
|
+
# in order to be used with the active job test helpers. Refer to
|
1434
|
+
# <tt>ActiveJob::QueueAdapters::TestAdapter</tt>.
|
1435
|
+
def queue_adapter_for_test: () -> ActiveJob::QueueAdapters::TestAdapter
|
1436
|
+
|
1437
|
+
# Asserts that the number of enqueued jobs matches the given number.
|
1438
|
+
#
|
1439
|
+
# def test_jobs
|
1440
|
+
# assert_enqueued_jobs 0
|
1441
|
+
# HelloJob.perform_later('david')
|
1442
|
+
# assert_enqueued_jobs 1
|
1443
|
+
# HelloJob.perform_later('abdelkader')
|
1444
|
+
# assert_enqueued_jobs 2
|
1445
|
+
# end
|
1446
|
+
#
|
1447
|
+
# If a block is passed, asserts that the block will cause the specified number of
|
1448
|
+
# jobs to be enqueued.
|
1449
|
+
#
|
1450
|
+
# def test_jobs_again
|
1451
|
+
# assert_enqueued_jobs 1 do
|
1452
|
+
# HelloJob.perform_later('cristian')
|
1453
|
+
# end
|
1454
|
+
#
|
1455
|
+
# assert_enqueued_jobs 2 do
|
1456
|
+
# HelloJob.perform_later('aaron')
|
1457
|
+
# HelloJob.perform_later('rafael')
|
1458
|
+
# end
|
1459
|
+
# end
|
1460
|
+
#
|
1461
|
+
# Asserts the number of times a specific job was enqueued by passing +:only+ option.
|
1462
|
+
#
|
1463
|
+
# def test_logging_job
|
1464
|
+
# assert_enqueued_jobs 1, only: LoggingJob do
|
1465
|
+
# LoggingJob.perform_later
|
1466
|
+
# HelloJob.perform_later('jeremy')
|
1467
|
+
# end
|
1468
|
+
# end
|
1469
|
+
#
|
1470
|
+
# Asserts the number of times a job except specific class was enqueued by passing +:except+ option.
|
1471
|
+
#
|
1472
|
+
# def test_logging_job
|
1473
|
+
# assert_enqueued_jobs 1, except: HelloJob do
|
1474
|
+
# LoggingJob.perform_later
|
1475
|
+
# HelloJob.perform_later('jeremy')
|
1476
|
+
# end
|
1477
|
+
# end
|
1478
|
+
#
|
1479
|
+
# +:only+ and +:except+ options accepts Class, Array of Class or Proc. When passed a Proc,
|
1480
|
+
# a hash containing the job's class and it's argument are passed as argument.
|
1481
|
+
#
|
1482
|
+
# Asserts the number of times a job is enqueued to a specific queue by passing +:queue+ option.
|
1483
|
+
#
|
1484
|
+
# def test_logging_job
|
1485
|
+
# assert_enqueued_jobs 2, queue: 'default' do
|
1486
|
+
# LoggingJob.perform_later
|
1487
|
+
# HelloJob.perform_later('elfassy')
|
1488
|
+
# end
|
1489
|
+
# end
|
1490
|
+
def assert_enqueued_jobs: (untyped number, ?only: untyped? only, ?except: untyped? except, ?queue: untyped? queue) { () -> untyped } -> untyped
|
1491
|
+
|
1492
|
+
# Asserts that no jobs have been enqueued.
|
1493
|
+
#
|
1494
|
+
# def test_jobs
|
1495
|
+
# assert_no_enqueued_jobs
|
1496
|
+
# HelloJob.perform_later('jeremy')
|
1497
|
+
# assert_enqueued_jobs 1
|
1498
|
+
# end
|
1499
|
+
#
|
1500
|
+
# If a block is passed, asserts that the block will not cause any job to be enqueued.
|
1501
|
+
#
|
1502
|
+
# def test_jobs_again
|
1503
|
+
# assert_no_enqueued_jobs do
|
1504
|
+
# # No job should be enqueued from this block
|
1505
|
+
# end
|
1506
|
+
# end
|
1507
|
+
#
|
1508
|
+
# Asserts that no jobs of a specific kind are enqueued by passing +:only+ option.
|
1509
|
+
#
|
1510
|
+
# def test_no_logging
|
1511
|
+
# assert_no_enqueued_jobs only: LoggingJob do
|
1512
|
+
# HelloJob.perform_later('jeremy')
|
1513
|
+
# end
|
1514
|
+
# end
|
1515
|
+
#
|
1516
|
+
# Asserts that no jobs except specific class are enqueued by passing +:except+ option.
|
1517
|
+
#
|
1518
|
+
# def test_no_logging
|
1519
|
+
# assert_no_enqueued_jobs except: HelloJob do
|
1520
|
+
# HelloJob.perform_later('jeremy')
|
1521
|
+
# end
|
1522
|
+
# end
|
1523
|
+
#
|
1524
|
+
# +:only+ and +:except+ options accepts Class, Array of Class or Proc. When passed a Proc,
|
1525
|
+
# a hash containing the job's class and it's argument are passed as argument.
|
1526
|
+
#
|
1527
|
+
# Asserts that no jobs are enqueued to a specific queue by passing +:queue+ option
|
1528
|
+
#
|
1529
|
+
# def test_no_logging
|
1530
|
+
# assert_no_enqueued_jobs queue: 'default' do
|
1531
|
+
# LoggingJob.set(queue: :some_queue).perform_later
|
1532
|
+
# end
|
1533
|
+
# end
|
1534
|
+
#
|
1535
|
+
# Note: This assertion is simply a shortcut for:
|
1536
|
+
#
|
1537
|
+
# assert_enqueued_jobs 0, &block
|
1538
|
+
def assert_no_enqueued_jobs: (?only: untyped? only, ?except: untyped? except, ?queue: untyped? queue) { () -> untyped } -> untyped
|
1539
|
+
|
1540
|
+
# Asserts that the number of performed jobs matches the given number.
|
1541
|
+
# If no block is passed, <tt>perform_enqueued_jobs</tt>
|
1542
|
+
# must be called around or after the job call.
|
1543
|
+
#
|
1544
|
+
# def test_jobs
|
1545
|
+
# assert_performed_jobs 0
|
1546
|
+
#
|
1547
|
+
# perform_enqueued_jobs do
|
1548
|
+
# HelloJob.perform_later('xavier')
|
1549
|
+
# end
|
1550
|
+
# assert_performed_jobs 1
|
1551
|
+
#
|
1552
|
+
# HelloJob.perform_later('yves')
|
1553
|
+
#
|
1554
|
+
# perform_enqueued_jobs
|
1555
|
+
#
|
1556
|
+
# assert_performed_jobs 2
|
1557
|
+
# end
|
1558
|
+
#
|
1559
|
+
# If a block is passed, asserts that the block will cause the specified number of
|
1560
|
+
# jobs to be performed.
|
1561
|
+
#
|
1562
|
+
# def test_jobs_again
|
1563
|
+
# assert_performed_jobs 1 do
|
1564
|
+
# HelloJob.perform_later('robin')
|
1565
|
+
# end
|
1566
|
+
#
|
1567
|
+
# assert_performed_jobs 2 do
|
1568
|
+
# HelloJob.perform_later('carlos')
|
1569
|
+
# HelloJob.perform_later('sean')
|
1570
|
+
# end
|
1571
|
+
# end
|
1572
|
+
#
|
1573
|
+
# This method also supports filtering. If the +:only+ option is specified,
|
1574
|
+
# then only the listed job(s) will be performed.
|
1575
|
+
#
|
1576
|
+
# def test_hello_job
|
1577
|
+
# assert_performed_jobs 1, only: HelloJob do
|
1578
|
+
# HelloJob.perform_later('jeremy')
|
1579
|
+
# LoggingJob.perform_later
|
1580
|
+
# end
|
1581
|
+
# end
|
1582
|
+
#
|
1583
|
+
# Also if the +:except+ option is specified,
|
1584
|
+
# then the job(s) except specific class will be performed.
|
1585
|
+
#
|
1586
|
+
# def test_hello_job
|
1587
|
+
# assert_performed_jobs 1, except: LoggingJob do
|
1588
|
+
# HelloJob.perform_later('jeremy')
|
1589
|
+
# LoggingJob.perform_later
|
1590
|
+
# end
|
1591
|
+
# end
|
1592
|
+
#
|
1593
|
+
# An array may also be specified, to support testing multiple jobs.
|
1594
|
+
#
|
1595
|
+
# def test_hello_and_logging_jobs
|
1596
|
+
# assert_nothing_raised do
|
1597
|
+
# assert_performed_jobs 2, only: [HelloJob, LoggingJob] do
|
1598
|
+
# HelloJob.perform_later('jeremy')
|
1599
|
+
# LoggingJob.perform_later('stewie')
|
1600
|
+
# RescueJob.perform_later('david')
|
1601
|
+
# end
|
1602
|
+
# end
|
1603
|
+
# end
|
1604
|
+
#
|
1605
|
+
# A proc may also be specified. When passed a Proc, the job's instance will be passed as argument.
|
1606
|
+
#
|
1607
|
+
# def test_hello_and_logging_jobs
|
1608
|
+
# assert_nothing_raised do
|
1609
|
+
# assert_performed_jobs(1, only: ->(job) { job.is_a?(HelloJob) }) do
|
1610
|
+
# HelloJob.perform_later('jeremy')
|
1611
|
+
# LoggingJob.perform_later('stewie')
|
1612
|
+
# RescueJob.perform_later('david')
|
1613
|
+
# end
|
1614
|
+
# end
|
1615
|
+
# end
|
1616
|
+
#
|
1617
|
+
# If the +:queue+ option is specified,
|
1618
|
+
# then only the job(s) enqueued to a specific queue will be performed.
|
1619
|
+
#
|
1620
|
+
# def test_assert_performed_jobs_with_queue_option
|
1621
|
+
# assert_performed_jobs 1, queue: :some_queue do
|
1622
|
+
# HelloJob.set(queue: :some_queue).perform_later("jeremy")
|
1623
|
+
# HelloJob.set(queue: :other_queue).perform_later("bogdan")
|
1624
|
+
# end
|
1625
|
+
# end
|
1626
|
+
def assert_performed_jobs: (untyped number, ?only: untyped? only, ?except: untyped? except, ?queue: untyped? queue) { () -> untyped } -> untyped
|
1627
|
+
|
1628
|
+
# Asserts that no jobs have been performed.
|
1629
|
+
#
|
1630
|
+
# def test_jobs
|
1631
|
+
# assert_no_performed_jobs
|
1632
|
+
#
|
1633
|
+
# perform_enqueued_jobs do
|
1634
|
+
# HelloJob.perform_later('matthew')
|
1635
|
+
# assert_performed_jobs 1
|
1636
|
+
# end
|
1637
|
+
# end
|
1638
|
+
#
|
1639
|
+
# If a block is passed, asserts that the block will not cause any job to be performed.
|
1640
|
+
#
|
1641
|
+
# def test_jobs_again
|
1642
|
+
# assert_no_performed_jobs do
|
1643
|
+
# # No job should be performed from this block
|
1644
|
+
# end
|
1645
|
+
# end
|
1646
|
+
#
|
1647
|
+
# The block form supports filtering. If the +:only+ option is specified,
|
1648
|
+
# then only the listed job(s) will not be performed.
|
1649
|
+
#
|
1650
|
+
# def test_no_logging
|
1651
|
+
# assert_no_performed_jobs only: LoggingJob do
|
1652
|
+
# HelloJob.perform_later('jeremy')
|
1653
|
+
# end
|
1654
|
+
# end
|
1655
|
+
#
|
1656
|
+
# Also if the +:except+ option is specified,
|
1657
|
+
# then the job(s) except specific class will not be performed.
|
1658
|
+
#
|
1659
|
+
# def test_no_logging
|
1660
|
+
# assert_no_performed_jobs except: HelloJob do
|
1661
|
+
# HelloJob.perform_later('jeremy')
|
1662
|
+
# end
|
1663
|
+
# end
|
1664
|
+
#
|
1665
|
+
# +:only+ and +:except+ options accepts Class, Array of Class or Proc. When passed a Proc,
|
1666
|
+
# an instance of the job will be passed as argument.
|
1667
|
+
#
|
1668
|
+
# If the +:queue+ option is specified,
|
1669
|
+
# then only the job(s) enqueued to a specific queue will not be performed.
|
1670
|
+
#
|
1671
|
+
# def test_assert_no_performed_jobs_with_queue_option
|
1672
|
+
# assert_no_performed_jobs queue: :some_queue do
|
1673
|
+
# HelloJob.set(queue: :other_queue).perform_later("jeremy")
|
1674
|
+
# end
|
1675
|
+
# end
|
1676
|
+
#
|
1677
|
+
# Note: This assertion is simply a shortcut for:
|
1678
|
+
#
|
1679
|
+
# assert_performed_jobs 0, &block
|
1680
|
+
def assert_no_performed_jobs: (?only: untyped? only, ?except: untyped? except, ?queue: untyped? queue) { () -> untyped } -> untyped
|
1681
|
+
|
1682
|
+
# Asserts that the job has been enqueued with the given arguments.
|
1683
|
+
#
|
1684
|
+
# def test_assert_enqueued_with
|
1685
|
+
# MyJob.perform_later(1,2,3)
|
1686
|
+
# assert_enqueued_with(job: MyJob, args: [1,2,3], queue: 'low')
|
1687
|
+
#
|
1688
|
+
# MyJob.set(wait_until: Date.tomorrow.noon).perform_later
|
1689
|
+
# assert_enqueued_with(job: MyJob, at: Date.tomorrow.noon)
|
1690
|
+
# end
|
1691
|
+
#
|
1692
|
+
# The +at+ and +args+ arguments also accept a proc.
|
1693
|
+
#
|
1694
|
+
# To the +at+ proc, it will get passed the actual job's at argument.
|
1695
|
+
#
|
1696
|
+
# def test_assert_enqueued_with
|
1697
|
+
# expected_time = ->(at) do
|
1698
|
+
# (Date.yesterday..Date.tomorrow).cover?(at)
|
1699
|
+
# end
|
1700
|
+
#
|
1701
|
+
# MyJob.set(at: Date.today.noon).perform_later
|
1702
|
+
# assert_enqueued_with(job: MyJob, at: expected_time)
|
1703
|
+
# end
|
1704
|
+
#
|
1705
|
+
# To the +args+ proc, it will get passed the actual job's arguments
|
1706
|
+
# Your proc needs to return a boolean value determining if
|
1707
|
+
# the job's arguments matches your expectation. This is useful to check only
|
1708
|
+
# for a subset of arguments.
|
1709
|
+
#
|
1710
|
+
# def test_assert_enqueued_with
|
1711
|
+
# expected_args = ->(job_args) do
|
1712
|
+
# assert job_args.first.key?(:foo)
|
1713
|
+
# end
|
1714
|
+
#
|
1715
|
+
# MyJob.perform_later(foo: 'bar', other_arg: 'No need to check in the test')
|
1716
|
+
# assert_enqueued_with(job: MyJob, args: expected_args, queue: 'low')
|
1717
|
+
# end
|
1718
|
+
#
|
1719
|
+
# If a block is passed, asserts that the block will cause the job to be
|
1720
|
+
# enqueued with the given arguments.
|
1721
|
+
#
|
1722
|
+
# def test_assert_enqueued_with
|
1723
|
+
# assert_enqueued_with(job: MyJob, args: [1,2,3], queue: 'low') do
|
1724
|
+
# MyJob.perform_later(1,2,3)
|
1725
|
+
# end
|
1726
|
+
#
|
1727
|
+
# assert_enqueued_with(job: MyJob, at: Date.tomorrow.noon) do
|
1728
|
+
# MyJob.set(wait_until: Date.tomorrow.noon).perform_later
|
1729
|
+
# end
|
1730
|
+
# end
|
1731
|
+
def assert_enqueued_with: (?job: untyped? job, ?args: untyped? args, ?at: untyped? at, ?queue: untyped? queue) { () -> untyped } -> untyped
|
1732
|
+
|
1733
|
+
# Asserts that the job has been performed with the given arguments.
|
1734
|
+
#
|
1735
|
+
# def test_assert_performed_with
|
1736
|
+
# MyJob.perform_later(1,2,3)
|
1737
|
+
#
|
1738
|
+
# perform_enqueued_jobs
|
1739
|
+
#
|
1740
|
+
# assert_performed_with(job: MyJob, args: [1,2,3], queue: 'high')
|
1741
|
+
#
|
1742
|
+
# MyJob.set(wait_until: Date.tomorrow.noon).perform_later
|
1743
|
+
#
|
1744
|
+
# perform_enqueued_jobs
|
1745
|
+
#
|
1746
|
+
# assert_performed_with(job: MyJob, at: Date.tomorrow.noon)
|
1747
|
+
# end
|
1748
|
+
#
|
1749
|
+
# The +at+ and +args+ arguments also accept a proc.
|
1750
|
+
#
|
1751
|
+
# To the +at+ proc, it will get passed the actual job's at argument.
|
1752
|
+
#
|
1753
|
+
# def test_assert_enqueued_with
|
1754
|
+
# expected_time = ->(at) do
|
1755
|
+
# (Date.yesterday..Date.tomorrow).cover?(at)
|
1756
|
+
# end
|
1757
|
+
#
|
1758
|
+
# MyJob.set(at: Date.today.noon).perform_later
|
1759
|
+
# assert_enqueued_with(job: MyJob, at: expected_time)
|
1760
|
+
# end
|
1761
|
+
#
|
1762
|
+
# To the +args+ proc, it will get passed the actual job's arguments
|
1763
|
+
# Your proc needs to return a boolean value determining if
|
1764
|
+
# the job's arguments matches your expectation. This is useful to check only
|
1765
|
+
# for a subset of arguments.
|
1766
|
+
#
|
1767
|
+
# def test_assert_performed_with
|
1768
|
+
# expected_args = ->(job_args) do
|
1769
|
+
# assert job_args.first.key?(:foo)
|
1770
|
+
# end
|
1771
|
+
# MyJob.perform_later(foo: 'bar', other_arg: 'No need to check in the test')
|
1772
|
+
#
|
1773
|
+
# perform_enqueued_jobs
|
1774
|
+
#
|
1775
|
+
# assert_performed_with(job: MyJob, args: expected_args, queue: 'high')
|
1776
|
+
# end
|
1777
|
+
#
|
1778
|
+
# If a block is passed, that block performs all of the jobs that were
|
1779
|
+
# enqueued throughout the duration of the block and asserts that
|
1780
|
+
# the job has been performed with the given arguments in the block.
|
1781
|
+
#
|
1782
|
+
# def test_assert_performed_with
|
1783
|
+
# assert_performed_with(job: MyJob, args: [1,2,3], queue: 'high') do
|
1784
|
+
# MyJob.perform_later(1,2,3)
|
1785
|
+
# end
|
1786
|
+
#
|
1787
|
+
# assert_performed_with(job: MyJob, at: Date.tomorrow.noon) do
|
1788
|
+
# MyJob.set(wait_until: Date.tomorrow.noon).perform_later
|
1789
|
+
# end
|
1790
|
+
# end
|
1791
|
+
def assert_performed_with: (?job: untyped? job, ?args: untyped? args, ?at: untyped? at, ?queue: untyped? queue) { () -> untyped } -> untyped
|
1792
|
+
|
1793
|
+
# Performs all enqueued jobs. If a block is given, performs all of the jobs
|
1794
|
+
# that were enqueued throughout the duration of the block. If a block is
|
1795
|
+
# not given, performs all of the enqueued jobs up to this point in the test.
|
1796
|
+
#
|
1797
|
+
# def test_perform_enqueued_jobs
|
1798
|
+
# perform_enqueued_jobs do
|
1799
|
+
# MyJob.perform_later(1, 2, 3)
|
1800
|
+
# end
|
1801
|
+
# assert_performed_jobs 1
|
1802
|
+
# end
|
1803
|
+
#
|
1804
|
+
# def test_perform_enqueued_jobs_without_block
|
1805
|
+
# MyJob.perform_later(1, 2, 3)
|
1806
|
+
#
|
1807
|
+
# perform_enqueued_jobs
|
1808
|
+
#
|
1809
|
+
# assert_performed_jobs 1
|
1810
|
+
# end
|
1811
|
+
#
|
1812
|
+
# This method also supports filtering. If the +:only+ option is specified,
|
1813
|
+
# then only the listed job(s) will be performed.
|
1814
|
+
#
|
1815
|
+
# def test_perform_enqueued_jobs_with_only
|
1816
|
+
# perform_enqueued_jobs(only: MyJob) do
|
1817
|
+
# MyJob.perform_later(1, 2, 3) # will be performed
|
1818
|
+
# HelloJob.perform_later(1, 2, 3) # will not be performed
|
1819
|
+
# end
|
1820
|
+
# assert_performed_jobs 1
|
1821
|
+
# end
|
1822
|
+
#
|
1823
|
+
# Also if the +:except+ option is specified,
|
1824
|
+
# then the job(s) except specific class will be performed.
|
1825
|
+
#
|
1826
|
+
# def test_perform_enqueued_jobs_with_except
|
1827
|
+
# perform_enqueued_jobs(except: HelloJob) do
|
1828
|
+
# MyJob.perform_later(1, 2, 3) # will be performed
|
1829
|
+
# HelloJob.perform_later(1, 2, 3) # will not be performed
|
1830
|
+
# end
|
1831
|
+
# assert_performed_jobs 1
|
1832
|
+
# end
|
1833
|
+
#
|
1834
|
+
# +:only+ and +:except+ options accepts Class, Array of Class or Proc. When passed a Proc,
|
1835
|
+
# an instance of the job will be passed as argument.
|
1836
|
+
#
|
1837
|
+
# If the +:queue+ option is specified,
|
1838
|
+
# then only the job(s) enqueued to a specific queue will be performed.
|
1839
|
+
#
|
1840
|
+
# def test_perform_enqueued_jobs_with_queue
|
1841
|
+
# perform_enqueued_jobs queue: :some_queue do
|
1842
|
+
# MyJob.set(queue: :some_queue).perform_later(1, 2, 3) # will be performed
|
1843
|
+
# HelloJob.set(queue: :other_queue).perform_later(1, 2, 3) # will not be performed
|
1844
|
+
# end
|
1845
|
+
# assert_performed_jobs 1
|
1846
|
+
# end
|
1847
|
+
#
|
1848
|
+
def perform_enqueued_jobs: (?only: untyped? only, ?except: untyped? except, ?queue: untyped? queue) { () -> untyped } -> untyped
|
1849
|
+
|
1850
|
+
# Accesses the queue_adapter set by ActiveJob::Base.
|
1851
|
+
#
|
1852
|
+
# def test_assert_job_has_custom_queue_adapter_set
|
1853
|
+
# assert_instance_of CustomQueueAdapter, HelloJob.queue_adapter
|
1854
|
+
# end
|
1855
|
+
def queue_adapter: () -> untyped
|
1856
|
+
|
1857
|
+
def clear_enqueued_jobs: () -> untyped
|
1858
|
+
|
1859
|
+
def clear_performed_jobs: () -> untyped
|
1860
|
+
|
1861
|
+
def jobs_with: (untyped jobs, ?only: untyped? only, ?except: untyped? except, ?queue: untyped? queue) { (untyped) -> untyped } -> untyped
|
1862
|
+
|
1863
|
+
def filter_as_proc: (untyped filter) -> untyped
|
1864
|
+
|
1865
|
+
def enqueued_jobs_with: (?only: untyped? only, ?except: untyped? except, ?queue: untyped? queue) { () -> untyped } -> untyped
|
1866
|
+
|
1867
|
+
def performed_jobs_with: (?only: untyped? only, ?except: untyped? except, ?queue: untyped? queue) { () -> untyped } -> untyped
|
1868
|
+
|
1869
|
+
def flush_enqueued_jobs: (?only: untyped? only, ?except: untyped? except, ?queue: untyped? queue) -> untyped
|
1870
|
+
|
1871
|
+
def prepare_args_for_assertion: (untyped args) -> untyped
|
1872
|
+
|
1873
|
+
def round_time_arguments: (untyped argument) -> untyped
|
1874
|
+
|
1875
|
+
def deserialize_args_for_assertion: (untyped job) -> untyped
|
1876
|
+
|
1877
|
+
def instantiate_job: (untyped payload) -> untyped
|
1878
|
+
|
1879
|
+
def queue_adapter_changed_jobs: () -> untyped
|
1880
|
+
|
1881
|
+
def validate_option: (?only: untyped? only, ?except: untyped? except) -> untyped
|
1882
|
+
end
|
1883
|
+
end
|
1884
|
+
|
1885
|
+
module ActiveJob
|
1886
|
+
module Timezones
|
1887
|
+
# nodoc:
|
1888
|
+
extend ActiveSupport::Concern
|
1889
|
+
end
|
1890
|
+
end
|
1891
|
+
|
1892
|
+
module ActiveJob
|
1893
|
+
module Translation
|
1894
|
+
# nodoc:
|
1895
|
+
extend ActiveSupport::Concern
|
1896
|
+
end
|
1897
|
+
end
|
1898
|
+
|
1899
|
+
module ActiveJob
|
1900
|
+
# Returns the version of the currently loaded Active Job as a <tt>Gem::Version</tt>
|
1901
|
+
def self.version: () -> untyped
|
1902
|
+
end
|
1903
|
+
|
1904
|
+
module ActiveJob
|
1905
|
+
extend ActiveSupport::Autoload
|
1906
|
+
end
|
1907
|
+
|
1908
|
+
module Rails
|
1909
|
+
module Generators
|
1910
|
+
class JobGenerator < Rails::Generators::NamedBase
|
1911
|
+
def self.default_generator_root: () -> untyped
|
1912
|
+
|
1913
|
+
def create_job_file: () -> untyped
|
1914
|
+
|
1915
|
+
def file_name: () -> untyped
|
1916
|
+
|
1917
|
+
def application_job_file_name: () -> untyped
|
1918
|
+
end
|
1919
|
+
end
|
1920
|
+
end
|