views:

68

answers:

1

What is the best way to run cron jobs on rails, when different machines have different jobs to do?

For example, server 1 runs cron job A, while server 2 runs cron job B

Is there a way to deploy the cron files along when we do a regular cap deploy?

+4  A: 

take a look at the whenever gem, http://github.com/javan/whenever

It is great for automating cron tasks with rails with a clear DSL. We have been using it production for several months now and it just works and is very lightweight. Some examples from their README:

 every 3.hours do
    runner "MyModel.some_process"
    rake "my:rake:task"
    command "/usr/bin/my_great_command"
  end

  every 1.day, :at => '4:30 am' do
    runner "MyModel.task_to_run_at_four_thirty_in_the_morning"
  end

  every :hour do # Many shortcuts available: :hour, :day, :month, :year, :reboot
    runner "SomeModel.ladeeda"
  end

  every :sunday, :at => '12pm' do # Use any day of the week or :weekend, :weekday
    runner "Task.do_something_great"
  end

The README is very thorough, but there is also a good screencast on railscasts: http://railscasts.com/episodes/164-cron-in-ruby

It easily integrates with capistrano with the following code (copied from README):

  after "deploy:symlink", "deploy:update_crontab"

  namespace :deploy do
    desc "Update the crontab file"
    task :update_crontab, :roles => :db do
      run "cd #{release_path} && whenever --update-crontab #{application}"
    end
  end

As far as machine specific, you could use a local config file or even symlink the config/schedule.rb file on deploy. I think I would include a local file that would be symlinked on deploy local_schedule.rb and then put this at the top of the config/schedule.rb

if File.exists?(File.dirname(__FILE__) + '/config/local_schedule.rb')
  require File.dirname(__FILE__) + '/local_schedule.rb'
end

Your schedule would run but then include anything local, just make sure it is symlinked before the cap task above is run and you should be good to go.

I hope this helps!

Geoff Lanotte
I love your answer and the railscast, thanks! My only quip is that the way to do the machine specific stuff is a little too complicated. Since Schedule.rb allows us to write ruby code, i wonder if there is a way to specify it there instead.I asked a related question here: http://stackoverflow.com/questions/3550770/finding-out-deployment-machine-you-are-on-in-code-railsAm i making sense?
ming yeow