rbs_rails 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|