A tale about ActiveJob

If you have been using Ruby on Rails for a while now, you've probably run into the problem where a long process is taking a lot of time on the server locking it for any new request.

The solution is fairly easy by just sending that long process into a background job, and there are a lot of great gems out there to help us get the job done:

The issue here is that each one of them have their own DSL, which makes it hard to change between them if you don't encapsulate the logic into a class or set of classes.

Rails 4.2 integrates now an ActiveJob module which intention is to encapsulate a background job API. A list of available adapters can be found here http://edgeapi.rubyonrails.org/classes/ActiveJob/QueueAdapters.html

Get started

ActiveJob comes with a generator to help us create a file to handle a long process or set of long processes. For example, let's say we want send emails on a background process.

First we need to create the job to handle this:

$ rails g job emails

This should create a file under the app/jobs directory, and may look like this:

class EmailsJob < ActiveJob::Base  
  queue_as :default

  def perform(*args)
    # Do something later
  end
end  

And let's say that anytime a user signs up into our site, we want to deliver them a welcome email.

A simple implementation for that action would be like this:

class UsersController < ApplicationController  
  def create
    @user = User.new(user_params)

     if @user.save
      UserMailer.welcome_email(user).deliver
      redirect_to @user, notice: 'Hey you just signed up, welcome!'
     else
      render :new
     end
   end
end  

With the EmailsJob class we just added, we can simply update the welcome_email method on the controller like so:

EmailsJob.perform_later(@user)  

And the implementation of the perform method on the EmailsJob class should look like this:

class EmailsJob < ActiveJob::Base  
  queue_as :default

  def perform(*args)
    UserMailer.welcome_email(user).deliver
  end
end  

This way the welcome email will now be sent on background.

Sending emails seems like a must-have for every application(or at least on my experience) and Rails understands this, that's why it includes a deliver_later method to achieve this:

UserMailer.welcome_email(user).deliver_later  

Connect the backend

We have not talk about on how to set the driver or adapter to handle the background jobs processing.

The implementation is really simple, and it actually part of the application.rb file

\#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 = :delayed_job
  end
end  

In the example above we configured the adapter to use delayed_job, but remember it can be sidekiq or resque. For mor information on adapters head to http://edgeapi.rubyonrails.org/classes/ActiveJob/QueueAdapters.html

Conclusion

You have probably used background jobs in the past probably to send emails, process images, zip some documents and things can get messy really quick without the right implementation.

ActiveJob is this kind of implementation, take advantage of it, it will make your like much easier.