4 Simple Steps to Implement “Delayed Job” in Rails by Jay April 22, 2013 3 Minutes ReadHere in this article, I going to tell you the best way to implement “delayed job” in rails “delayed_job” is a ruby gem used to execute tasks as a background process in Rails environment, increasing page rendering speed. Delayed::Job (or DJ) allows you to move jobs into the background for asynchronous processing. Why you need a background process and is it really that important! Let’s consider a scenario where a mailing application needs to send emails to a huge list of recipients. In such cases it is obvious that the processing time is too long, annoying the users. Here are some of key points to consider: Incredibly quick & easy to get rolling No addition to your “stack”, runs just fine with ActiveRecord Good choice for beginners while migrating code from foreground to the background Hence, it’s only wise to move the long running tasks as a background process by using “delayed_job” gem. Detailed steps to integrate delayed job in a Rails application Step# 1 Add gem to the Gemfile “delayed_job” supports multiple back-ends for storing the job queue To use “delayed_job” with Active Record, use gem ‘delayed_job_active_record’ To use “delayed_job” with Mongoid, use gem ‘delayed_job_mongoid’ Example /Gemfile.rb gem ‘delayed_job_active_record’, ‘4.0.3’ Run “bundle install” to install the “delayed_job” gem Step# 2 Generate the related file for the Job run Generate related files required to run the background job by running the following command rails g delayed_job:active_record It adds following files to the application A Script named “delayed_job” inside “/bin” folder to run the jobs which are in queue. Migration file to create a table to store the job with other information such as priority, attempts, handler, last_error, run_at, locked_at, failed_at, locked_by, queue. Run the migration file by using the following command rails db:migrate Set the queue_adapter in config/application.rb config.active_job.queue_adapter = :delayed_job If you are using the protected_attributes gem, it must appear before delayed_job in your gemfile. If your jobs are failing with: Setup Delayed::Job config in an initializer (config/initializers/delayed_job_config.rb) Delayed::Worker.destroy_failed_jobs = false Delayed::Worker.sleep_delay = 60 Delayed::Worker.max_attempts = 3 Delayed::Worker.max_run_time = 5.minutes Delayed::Worker.read_ahead = 10 Delayed::Worker.default_queue_name = ‘default’ Delayed::Worker.delay_jobs = !Rails.env.test? Delayed::Worker.raise_signal_exceptions = :term Delayed::Worker.logger = Logger.new(File.join(Rails.root, ‘log’, ‘delayed_job.log’)) Step# 3 Replace script/delayed_job with bin/delayed_job Start up the jobs process There are two ways to do this. If application is in development mode, we would use the below rake task instead. rake jobs:work If application is in production mode, then it is preferred to use the “delayed_job” script. This demonizes the job process and allows multiple background processes to be spawned. To use this, pursue the following steps Add gem “daemons” to your Gemfile Run bundle install Make sure you’ve run rails generate delayed_job If you want to just run all available jobs and exit you can use rake jobs:workoff Work off queues by setting the QUEUE or QUEUES environment variable. QUEUE=tracking rake jobs:work QUEUES=mailers,tasks rake jobs:work Step# 4 Add task to run in background In Controller just call .delay.method(params) on any object and it will be processed in the background. Example: UsersController before adding to background job [code language=”html”] class UsersController < ApplicationController def send_email User.find_each(is_subscribed: true) do |user| NewsMailer.newsletter_mail(user).deliver flash[:notice] = "Mail delivered" redirect_to root_path end end end [/code] UsersController after adding to background job [code language=”html”] class UsersController < ApplicationController def send_email User.find_each(is_subscribed: true) do |user| # add .delay method to add it to background process. In case of mail sending remove the .deliver method to make it work. NewsMailer.delay.newsletter_mail(user) flash[:notice] = "Mail delivered" redirect_to root_path end end end [/code] Advantages of implementing above steps: No more waiting for a response, after clicking a link to do a big stuff. Just call .delay.method(params) on any object and it processes in the background. Job objects are serialized to yaml and stored in the delayed_jobs table, so they can be restored by the job runner later. It automatically retries on failure. If a method throws an exception it’s caught and the method reruns later. The method retries up to 25 times at increasingly longer intervals until it passes. “delayed_job” gem maintains log by creating a log file “/log/delayed_job.log” I am sure this article will give you a clear idea about the way to implement “delayed job” in rails. You can share your thoughts with comments if I have missed anything or if you want to know more. Do you work on or use Ruby on Rails? Let’s Discuss! Related Posts: Asynchronous processing with Sidekiq gem in Rails How to implement “Multiple Database(DB) Connection” in Rails3 How to Implement Event Calendar in Rails App Tags: Rails, Ruby Jayadev Das firstname.lastname@example.org Do what you do best in – that’s what I’ve always believed in and that’s what I preach. Over the past 25+ years (yup that’s my expertise ‘n’ experience in the Information Technology domain), I’ve been consulting to small, medium and large companies ‘bout Web Technologies, Mobile Future as well as on the good-and-bad of tech. Blogger, International Business Advisor, Web Technology Expert, Sales Guru, Startup Mentor, Insurance Sales Portal Expert & a Tennis Player. And top of all – a complete family man!