@@ -39,8 +39,8 @@ runs jobs with an in-process thread pool. Jobs will run asynchronously, but any
39
39
jobs in the queue will be dropped upon restart.
40
40
41
41
42
- Creating a Job
43
- --------------
42
+ Create and Enqueue Jobs
43
+ -----------------------
44
44
45
45
This section will provide a step-by-step guide to creating a job and enqueuing it.
46
46
@@ -127,6 +127,10 @@ That's it!
127
127
[ `perform_later` ] : https://api.rubyonrails.org/classes/ActiveJob/Enqueuing/ClassMethods.html#method-i-perform_later
128
128
[ `set` ] : https://api.rubyonrails.org/classes/ActiveJob/Core/ClassMethods.html#method-i-set
129
129
130
+ ### Enqueue Jobs in Bulk
131
+
132
+ You can enqueue multiple jobs at once using [ ` perform_all_later ` ] ( https://api.rubyonrails.org/classes/ActiveJob.html#method-c-perform_all_later ) . For more details see [ Bulk Enqueuing] ( #bulk-enqueuing ) .
133
+
130
134
Job Execution
131
135
-------------
132
136
@@ -406,6 +410,103 @@ end
406
410
[ `around_perform` ] : https://api.rubyonrails.org/classes/ActiveJob/Callbacks/ClassMethods.html#method-i-around_perform
407
411
[ `after_perform` ] : https://api.rubyonrails.org/classes/ActiveJob/Callbacks/ClassMethods.html#method-i-after_perform
408
412
413
+ Please note that when enqueuing jobs in bulk using ` perform_all_later ` ,
414
+ callbacks such as ` around_enqueue ` will not be triggered on the individual jobs.
415
+ See [ Bulk Enqueuing Callbacks] ( #bulk-enqueue-callbacks ) .
416
+
417
+ Bulk Enqueuing
418
+ --------------
419
+
420
+ You can enqueue multiple jobs at once using
421
+ [ ` perform_all_later ` ] ( https://api.rubyonrails.org/classes/ActiveJob.html#method-c-perform_all_later ) .
422
+ Bulk enqueuing reduces the number of round trips to the queue data store (like
423
+ Redis or a database), making it a more performant operation than enqueuing the
424
+ same jobs individually.
425
+
426
+ ` perform_all_later ` is a top-level API on Active Job. It accepts instantiated
427
+ jobs as arguments (note that this is different from ` perform_later ` ).
428
+ ` perform_all_later ` does call ` perform ` under the hood. The arguments passed to
429
+ ` new ` will be passed on to ` perform ` when it's eventually called.
430
+
431
+ Here is an example calling ` perform_all_later ` with ` GuestCleanupJob ` instances:
432
+
433
+ ``` ruby
434
+ # Create jobs to pass to `perform_all_later`.
435
+ # The arguments to `new` are passed on to `perform`
436
+ guest_cleanup_jobs = Guest .all.map { |guest | GuestsCleanupJob .new (guest) }
437
+
438
+ # Will enqueue a separate job for each instance of `GuestCleanupJob`
439
+ ActiveJob .perform_all_later(guest_cleanup_jobs)
440
+
441
+ # Can also use `set` method to configure options before bulk enqueuing jobs.
442
+ guest_cleanup_jobs = Guest .all.map { |guest | GuestsCleanupJob .new (guest).set(wait: 1 .day) }
443
+
444
+ ActiveJob .perform_all_later(guest_cleanup_jobs)
445
+ ```
446
+
447
+ ` perform_all_later ` logs the number of jobs successfully enqueued, for example
448
+ if ` Guest.all.map ` above resulted in 3 ` guest_cleanup_jobs ` , it would log
449
+ ` Enqueued 3 jobs to Async (3 GuestsCleanupJob) ` (assuming all were enqueued).
450
+
451
+ The return value of ` perform_all_later ` is ` nil ` . Note that this is different
452
+ from ` perform_later ` , which returns the instance of the queued job class.
453
+
454
+ ### Enqueue Multiple Active Job Classes
455
+
456
+ With ` perform_all_later ` , it's also possible to enqueue different Active Job
457
+ class instances in the same call. For example:
458
+
459
+ ``` ruby
460
+ class ExportDataJob < ApplicationJob
461
+ def perform (* args )
462
+ # Export data
463
+ end
464
+ end
465
+
466
+ class NotifyGuestsJob < ApplicationJob
467
+ def perform (* guests )
468
+ # Email guests
469
+ end
470
+ end
471
+
472
+ # Instantiate job instances
473
+ cleanup_job = GuestsCleanupJob .new (guest)
474
+ export_job = ExportDataJob .new (data)
475
+ notify_job = NotifyGuestsJob .new (guest)
476
+
477
+ # Enqueues job instances from multiple classes at once
478
+ ActiveJob .perform_all_later(cleanup_job, export_job, notify_job)
479
+ ```
480
+
481
+ ### Bulk Enqueue Callbacks
482
+
483
+ When enqueuing jobs in bulk using ` perform_all_later ` , callbacks such as
484
+ ` around_enqueue ` will not be triggered on the individual jobs. This behavior is
485
+ in line with other Active Record bulk methods. Since callbacks run on individual
486
+ jobs, they can't take advantage of the bulk nature of this method.
487
+
488
+ However, the ` perform_all_later ` method does fire an
489
+ [ ` enqueue_all.active_job ` ] ( active_support_instrumentation.html#enqueue-all-active-job )
490
+ event which you can subscribe to using ` ActiveSupport::Notifications ` .
491
+
492
+ The method
493
+ [ ` successfully_enqueued? ` ] ( https://api.rubyonrails.org/classes/ActiveJob/Core.html#method-i-successfully_enqueued-3F )
494
+ can be used to find out if a given job was successfully enqueued.
495
+
496
+ ### Queue Backend Support
497
+
498
+ For ` perform_all_later ` , bulk enqueuing needs to be backed by the [ queue
499
+ backend] ( #backends ) .
500
+
501
+ For example, Sidekiq has a ` push_bulk ` method, which can push a large number of
502
+ jobs to Redis and prevent the round trip network latency. GoodJob also supports
503
+ bulk enqueuing with the ` GoodJob::Bulk.enqueue ` method. The new queue backend
504
+ [ ` Solid Queue ` ] ( https://github.com/basecamp/solid_queue/pull/93 ) has added
505
+ support for bulk enqueuing as well.
506
+
507
+ If the queue backend does * not* support bulk enqueuing, ` perform_all_later ` will
508
+ enqueue jobs one by one.
509
+
409
510
Action Mailer
410
511
------------
411
512
0 commit comments