Search This Blog

February 9, 2011

No more cron jobs. Schedule jobs through rufus-scheduler in rails.

In the project that I'm working currently, I was asked to look out for ways to replace the scheduling jobs through crontab in favour of some scheduler that can control/schedule run the tasks at regular interval as long as the application is up and running. Thanks to my comrade in Dev-Ops team (Ranjib Dey) who  directing my attention to rufus-scheduler.

rufus-scheduler - Things can't be simpler! Let us see how simple it is in action with a sample code 

First step to usage is install the gem; so, find below the command for the same. You run it from the root of your application folder and I assume that you use rvm (if not, prefix the command with - sudo )

> gem install rufus-scheduler

Now, when the rails application gets kick-started, it reads all .rb files under config/initializers directory as part of its initialization process. This step in rails start-up, is what we'll take advantage of. So, let us create a new file, say my_tasks_scheduler.rb, in config/initializers directory.

<my_rails_app>

   | -- app

   | -- config

          | -- initializers

                    | -- my_tasks_scheduler.rb

   | -- db

   | -- ...

   | -- ...

   | -- lib

          | -- tasks

                    | -- tempfile.rake

The contents of the file my_tasks_scheduler.rb would be like:


require 'rufus/scheduler'  # Need this to make use of Rufus::Scheduler

require 'rubygems'   # Need this to make use of any Gem, in our case it is rufus-scheduler

require 'rake'     # Need this to make use of Rake::Task

#  'tempfile.rake' is the rake file I had defined under lib/tasks directory in my rails application

load File.join(RAILS_ROOT'lib''tasks''tempfile.rake')
# 'misc.rake' is the rake file defined under railties/lib/tasks directory of the installed rails version that your application makes use of.     

# 'misc.rake' is not required to be loaded if none of your rake tasks that you invoke are dependent on :environment task, directly or indirectly
# If this file is not loaded, you would see an error message like "Don't know how to build task :environment"
load File.join('lib', 'tasks', 'misc.rake')  

# OPTION 1: If you want to run the scheduler as part of your very own rails process then you may adopt this option

temp_files_cleaning_scheduler = Rufus::Scheduler.start_new
# Making use of the syntax used in Crontab

temp_files_cleaning_scheduler.cron '*/1 * * * *' do  

  task = Rake::Task["tempfile:delete_all"

  task.reenable  # If only you do this, will your rake task run the next time you invoke it.

  task.invoke
end


#OPTION 2: If for whatever reason (say, for performance reasons) you want to run your rake tasks as seperate process independent of your rails application, then you may adopt this option


temp_files_cleaning_scheduler = Rufus::Scheduler.start_new  
#Making use of a more intutive approach, instead of Cron syntax

temp_files_cleaning_scheduler.every "1m" do  
    # Programmatically, kick-starting the rake task from the command line

   system "rake tempfile:delete_all RAILS_ENV=#{RAILS.env}"  

end


And that is it, you are all set for action... 


Additional references that are worth reading are mentioned below: