aboutsummaryrefslogtreecommitdiffstats
path: root/guides/source/active_job_basics.md
diff options
context:
space:
mode:
Diffstat (limited to 'guides/source/active_job_basics.md')
-rw-r--r--guides/source/active_job_basics.md144
1 files changed, 92 insertions, 52 deletions
diff --git a/guides/source/active_job_basics.md b/guides/source/active_job_basics.md
index e2f13d557a..3046a62778 100644
--- a/guides/source/active_job_basics.md
+++ b/guides/source/active_job_basics.md
@@ -1,3 +1,5 @@
+**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+
Active Job Basics
=================
@@ -23,7 +25,7 @@ clean-ups, to billing charges, to mailings. Anything that can be chopped up
into small units of work and run in parallel, really.
-The Purpose of the Active Job
+The Purpose of Active Job
-----------------------------
The main point is to ensure that all Rails apps will have a job infrastructure
in place, even if it's in the form of an "immediate runner". We can then have
@@ -41,10 +43,12 @@ This section will provide a step-by-step guide to creating a job and enqueuing i
### Create the Job
Active Job provides a Rails generator to create jobs. The following will create a
-job in `app/jobs`:
+job in `app/jobs` (with an attached test case under `test/jobs`):
```bash
$ bin/rails generate job guests_cleanup
+invoke test_unit
+create test/jobs/guests_cleanup_job_test.rb
create app/jobs/guests_cleanup_job.rb
```
@@ -52,12 +56,8 @@ You can also create a job that will run on a specific queue:
```bash
$ bin/rails generate job guests_cleanup --queue urgent
-create app/jobs/guests_cleanup_job.rb
```
-As you can see, you can generate jobs just like you use other generators with
-Rails.
-
If you don't want to use a generator, you could create your own file inside of
`app/jobs`, just make sure that it inherits from `ActiveJob::Base`.
@@ -78,15 +78,18 @@ end
Enqueue a job like so:
```ruby
-MyJob.enqueue record # Enqueue a job to be performed as soon the queueing system is free.
+# Enqueue a job to be performed as soon the queueing system is free.
+MyJob.perform_later record
```
```ruby
-MyJob.enqueue_at Date.tomorrow.noon, record # Enqueue a job to be performed tomorrow at noon.
+# Enqueue a job to be performed tomorrow at noon.
+MyJob.set(wait_until: Date.tomorrow.noon).perform_later(record)
```
```ruby
-MyJob.enqueue_in 1.week, record # Enqueue a job to be performed 1 week from now.
+# Enqueue a job to be performed 1 week from now.
+MyJob.set(wait: 1.week).perform_later(record)
```
That's it!
@@ -99,41 +102,23 @@ If no adapter is set, the job is immediately executed.
### Backends
-Active Job has adapters for the following queueing backends:
-
-* [Backburner](https://github.com/nesquena/backburner)
-* [Delayed Job](https://github.com/collectiveidea/delayed_job)
-* [Qu](https://github.com/bkeepers/qu)
-* [Que](https://github.com/chanks/que)
-* [QueueClassic 2.x](https://github.com/ryandotsmith/queue_classic/tree/v2.2.3)
-* [Resque 1.x](https://github.com/resque/resque/tree/1-x-stable)
-* [Sidekiq](https://github.com/mperham/sidekiq)
-* [Sneakers](https://github.com/jondot/sneakers)
-* [Sucker Punch](https://github.com/brandonhilkert/sucker_punch)
-
-#### Backends Features
-
-| | Async | Queues | Delayed | Priorities | Timeout | Retries |
-|-----------------------|-------|---------|---------|-------------|---------|---------|
-| **Backburner** | Yes | Yes | Yes | Yes | Job | Global |
-| **Delayed Job** | Yes | Yes | Yes | Job | Global | Global |
-| **Que** | Yes | Yes | Yes | Job | No | Job |
-| **Queue Classic** | Yes | Yes | Gem | No | No | No |
-| **Resque** | Yes | Yes | Gem | Queue | Global | Yes |
-| **Sidekiq** | Yes | Yes | Yes | Queue | No | Job |
-| **Sneakers** | Yes | Yes | No | Queue | Queue | No |
-| **Sucker Punch** | Yes | Yes | Yes | No | No | No |
-| **Active Job Inline** | No | Yes | N/A | N/A | N/A | N/A |
-| **Active Job** | Yes | Yes | Yes | No | No | No |
-
-### Change Backends
-
-You can easily change your adapter:
+Active Job has built-in adapters for multiple queueing backends (Sidekiq,
+Resque, Delayed Job and others). To get an up-to-date list of the adapters
+see the API Documentation for [ActiveJob::QueueAdapters](http://api.rubyonrails.org/classes/ActiveJob/QueueAdapters.html).
+
+### Setting the Backend
+
+You can easily set your queueing backend:
```ruby
-# be sure to have the adapter gem in your Gemfile and follow the adapter specific
-# installation and deployment instructions
-YourApp::Application.config.active_job.queue_adapter = :sidekiq
+# config/application.rb
+module YourApp
+ class Application < Rails::Application
+ # Be sure to have the adapter's gem in your Gemfile and follow
+ # the adapter's specific installation and deployment instructions.
+ config.active_job.queue_adapter = :sidekiq
+ end
+end
```
@@ -150,7 +135,7 @@ class GuestsCleanupJob < ActiveJob::Base
end
```
-Also you can prefix the queue name for all your jobs using
+You can prefix the queue name for all your jobs using
`config.active_job.queue_name_prefix` in `application.rb`:
```ruby
@@ -167,8 +152,62 @@ class GuestsCleanupJob < ActiveJob::Base
#....
end
-# Now your job will run on queue production_low_priority on your production
-# environment and on beta_low_priority on your beta environment
+# Now your job will run on queue production_low_priority on your
+# production environment and on staging_low_priority on your staging
+# environment
+```
+
+The default queue name prefix delimiter is '\_'. This can be changed by setting
+`config.active_job.queue_name_delimiter` in `application.rb`:
+
+```ruby
+# config/application.rb
+module YourApp
+ class Application < Rails::Application
+ config.active_job.queue_name_prefix = Rails.env
+ config.active_job.queue_name_delimiter = '.'
+ end
+end
+
+# app/jobs/guests_cleanup.rb
+class GuestsCleanupJob < ActiveJob::Base
+ queue_as :low_priority
+ #....
+end
+
+# Now your job will run on queue production.low_priority on your
+# production environment and on staging.low_priority on your staging
+# environment
+```
+
+If you want more control on what queue a job will be run you can pass a `:queue`
+option to `#set`:
+
+```ruby
+MyJob.set(queue: :another_queue).perform_later(record)
+```
+
+To control the queue from the job level you can pass a block to `#queue_as`. The
+block will be executed in the job context (so you can access `self.arguments`)
+and you must return the queue name:
+
+```ruby
+class ProcessVideoJob < ActiveJob::Base
+ queue_as do
+ video = self.arguments.first
+ if video.owner.premium?
+ :premium_videojobs
+ else
+ :videojobs
+ end
+ end
+
+ def perform(video)
+ # do process video
+ end
+end
+
+ProcessVideoJob.perform_later(Video.last)
```
NOTE: Make sure your queueing backend "listens" on your queue name. For some
@@ -178,8 +217,8 @@ backends you need to specify the queues to listen to.
Callbacks
---------
-Active Job provides hooks during the lifecycle of a job. Callbacks allow you to
-trigger logic during the lifecycle of a job.
+Active Job provides hooks during the life cycle of a job. Callbacks allow you to
+trigger logic during the life cycle of a job.
### Available callbacks
@@ -197,7 +236,7 @@ class GuestsCleanupJob < ActiveJob::Base
queue_as :default
before_enqueue do |job|
- # do somthing with the job instance
+ # do something with the job instance
end
around_perform do |job, block|
@@ -213,7 +252,7 @@ end
```
-ActionMailer
+Action Mailer
------------
One of the most common jobs in a modern web application is sending emails outside
@@ -231,12 +270,13 @@ UserMailer.welcome(@user).deliver_later
GlobalID
--------
+
Active Job supports GlobalID for parameters. This makes it possible to pass live
Active Record objects to your job instead of class/id pairs, which you then have
to manually deserialize. Before, jobs would look like this:
```ruby
-class TrashableCleanupJob
+class TrashableCleanupJob < ActiveJob::Base
def perform(trashable_class, trashable_id, depth)
trashable = trashable_class.constantize.find(trashable_id)
trashable.cleanup(depth)
@@ -247,14 +287,14 @@ end
Now you can simply do:
```ruby
-class TrashableCleanupJob
+class TrashableCleanupJob < ActiveJob::Base
def perform(trashable, depth)
trashable.cleanup(depth)
end
end
```
-This works with any class that mixes in `ActiveModel::GlobalIdentification`, which
+This works with any class that mixes in `GlobalID::Identification`, which
by default has been mixed into Active Model classes.