Wednesday, 1 February 2012

Handling Background Jobs in Rails 3.2

Hi everybody,
What's up!

Today I am going to discuss about the background tasks management in rails.

Suppose we have a UserMailer which sends email to the users once they have successfully completed the registration process. Something like this:

class UserMailer < ActionMailer::Base
  default :from => "admin@example.com"
  def registration_confirmation(user)
    mail(:to => user.email, :subject => "Registration Confirmation")
  end
end

And in the controller,

def create
    @user = User.new(params[:user])
    if @user.save
      UserMailer.registration_confirmation(@user).deliver
      redirect_to root_url, :notice => "Signed up! Please check confirmation mail!"
    else
      render "sign_up"
    end
end



After the user hits the "Create User" button, he has to wait for some time while their mail is being delivered.
During this process, rails is busy and can't respond to any other requests.
This is a very bad user experience. After all why should one has to wait for some time unnecessarily.

Now there are many gems and plugins available to handle the background jobs. I prefer to use "delayed_job" gem.
Firstly, because it stores the jobs queue in the database table. Hence, no memory leak or loss of data.
Secondly, it's very easy to implement.

So, let's see what are the steps involved:

1) add:  gem 'delayed_job_active record' to the gemfile and run 'bundle install'.

2) Next, we need the jobs table so run the commands:
   $ rails generate delayed_job:active_record
   $ rake db:migrate

3) Next go to the controller and just replace the line
    UserMailer.registration_confirmation(@user).deliver
    with,
    UserMailer.delay.registration_confirmation(@user)

4) $ rake jobs:work

Step 4 will look for any new job in the "delayed_jobs" table and execute it in the background.

This was easy. We can add many more features to the "delayed_jobs" gem for which I suggest you to checkout this Github Link.

Thanks!!


3 comments:

  1. Where I must create "UserMailer" class?

    ReplyDelete
  2. Hope this liknk might help:
    http://guides.rubyonrails.org/action_mailer_basics.html

    ReplyDelete
  3. It's a nice gem to handle background process.
    (At my case when I need to multiple emails to multiple recipients).

    Just a minor correction in step-1
    1) add: gem 'delayed_job_active record'
    An underscore is missing "delayed_job_active_record"

    Thanks man, You saved my lots of time & effort.

    ReplyDelete