This post was a featured article in Ruby Weekly.
With the announcement of Rails 4.2 came some exciting news: Rails now has built-in support for executing jobs in the background using Active Job. The ability to schedule newsletters, follow-up emails, and database housekeeping tasks is vital to almost any production application. In the past, developers had to hand-roll this functionality, and configuration varied between different queueing services. With the release of Rails 4.2, setting up jobs to be executed by workers at a later time is standardized. In this article, we’ll take a look at how to set up Active Job and use it to send a follow-up email to a new user.
You’ll need Rails 4.2.0beta1 or greater if you want to Active Job available by default (in older versions of Rails, you can require it as a gem). This tutorial is based on Rails 4.2.0beta2 (edge Rails). If you want to use edge Rails, use
gem 'rails', github: 'rails/rails' in your
Gemfile, and run
Setting Up Resque
In order to send emails outside of our main application process, we’ll need to make use of a queueing system. There are many choices of technology for setting up background workers available, and Active Job abstracts the differences between them. Today we’ll use Resque, as it’s widely-used and stable.
To use Resque, you’ll need to make sure you have Redis installed. If you don’t, I recommend getting it with Homebrew. Otherwise, you can follow the instructions for download from the official site. Once it’s set up, make sure
redis-server is running.
The next step is to install and configure the Resque gem. We’ll also need
resque-scheduler to use ActiveJob. Add them the
gem 'resque' and
gem 'resque-scheduler' and
bundle install. We’ll also need to create a Resque configuration file:
1 2 3 4
We’ll also require the Resque and Resque Scheduler rake tasks, so we can start our workers and scheduler with rake:
1 2 3 4 5 6 7 8 9 10 11
We can now start a worker with
QUEUE=* rake environment resque:work. If everything’s working right, we should be able to see it in the Resque console. Run
resque-web and visit
http://0.0.0.0:5678/overview. If you see “0 of 1 Workers Working”, all’s well. We’ll also need to boot up the scheduler in a separate process with
rake environment resque:scheduler.
Creating the Mailer
Now that we have a worker, we need it an email to send. Let’s imagine that we want to send a follow up email to a user that recently registered for our site. We’ll create a
UserMailer, with a
follow_up_email method that takes an email address.
1 2 3 4 5 6 7 8 9 10 11 12
We’ll also need to write a follow-up email template.
1 2 3 4
Creating the Job
Now that we have a working mailer, we can set up Active Job. All we really need to do is configure it to use the Resque adapter.
1 2 3
Next, we’ll create a job that tells the background worker to send the email. The conventions for a
job include: giving it a
queue_as, and defining a
1 2 3 4 5 6 7 8 9
Now when a user signs up, we can have the
UsersController enqueue the job for execution at a later time. Although you would probably delay the job a few days in a real application, we’ll just wait 10 seconds for easier testing.
1 2 3 4 5 6 7 8 9 10 11 12 13
To make this work, we’ll need some routes and a view template:
1 2 3 4 5
1 2 3 4 5 6
Setting Up Mailcatcher
Before we try our job, we’ll want to make sure we can intercept the emails we’re expecting the mailer to send. To achieve this, we’ll use the
mailcatcher gem. Do a global install with
gem install mailcatcher, and run
mailcatcher. Once we configure Action Mailer to send the emails to
localhost:1025 via smtp, we’ll be able to view intercepted emails at
1 2 3 4 5 6 7
Trying It Out
Now everything is set up. To try it out, we’ll sign up as a new user and watch the job get enqueued in the queue, then catch the mail in Mailcatcher. At this point, we have four processes running:
QUEUE=* rake environment resque:work
rake environment resque:scheduler
In your browser, view the Resque dashboard at
http:/http://0.0.0.0:5678. In another tab, visit
http://127.0.0.1:1080 to see the Mailcatcher dashboard.
Now, for the moment of truth. Visit
localhost:3000/users/new and sign up as a new user. Ten seconds later, a new job will appear in the
emails queue of the Resque dashboard. Just afterward, the email will appear in Mailcatcher.
Using Acive Job with Action Mailer
The pattern we’ve written here woks for scheduling any job. But, since ActiveJob is now baked into ActionMailer, we can also schedule the job directly with the
UserMailer in the
1 2 3 4 5 6 7 8 9
Active Job makes scheduling background jobs easier. It’s also a great way to set up your job infrastructure without knowing too much about what queueing system you’re using. If you needed to switch to Sidekiq or Delayed Job in the future, it would be as simple as setting ActiveJob to the appropriate adapter.
It can be a little bit tricky to get Active Job set up correctly. Hopefully, this tutorial made the process a little more transparent for you.
Until next time,