Whenever

Published on and tagged with configuration  ruby on rails

Most web applications have to perform some periodic tasks. For this purpose, you usually define some cron jobs.

With the “whenever” Ruby gem you can define those cron jobs directly in your Rails application.

After installing the gem (with “gem install javan-whenever”) you either have to create the file “/config/schedule.rb” manually, or you can use “wheneverize” to generate this file (call “wheneverize .” from your project root). You can then add your application-specific cron jobs to this file.

For example, let’s say you want to clean up the users table and remove all users who didn’t activate their accounts, then you would write something like:

every 1.day, :at => '2am' do
  runner "User.cleanup_inactive_users"
end

This will execute the “cleanup_inactive_users” method of the “User” model daily at 2am (you could also use “every :friday do” to run it every friday, or “every 2.hours do” to run it every two hours, and so on) . The “runner” keyword allows you to execute Ruby code (it uses “script/runner”, hence the name). You can also use “command” to execute command line tools, or “rake” for running rake tasks.

So far we simply described our cron job, though no cron job is active yet. To change this, we have to tell cron about our cron job with:

whenever --update-crontab example

“example” is a unique identifier for our application, and is used by “whenever” to determine which cron jobs it has to modify when you update “schedule.rb” and re-run the above command. It is probably best to put this command in the deployment script of your application to keep your cron jobs up-to-date.

With “crontab -l” we can see the job(s) added by “whenever”:

# Begin Whenever generated tasks for: example
0 2 * * * /home/dho/projects/example/script/runner -e production "User.cleanup_inactive_users"
# End Whenever generated tasks for: example

With that, our cron job should be executed like any other cron job on our system.

I hope I could give you a short overview about this quite useful gem, for more information see:
http://github.com/javan/whenever
ASCIIcasts “Episode 164 – Cron in Ruby”

6 comments baked

  • dezpo

    Nice features. Any alternatives in Cake?

  • cakebaker

    @dezpo: Thanks for your comment!

    I’m not aware of any alternatives in CakePHP. However, as long as you have Ruby on your server (Rails is not required), you should be able to use “whenever” with CakePHP. The only “restriction” is that you have to use “command” when defining the jobs. But else it should work. Give it a try ;-)

  • Eddie

    Very nice article.

    Does this actually eliminate any overhead, or just provide a manner to create Cron tabs from within code. I guess I am asking why not jump to crontab -e and enter the result.

  • cakebaker

    @Eddie: Thanks for your comment!

    It is simply a way to define cron jobs from within your application. Conceptually it sits on top of crontab, so it adds more “overhead” ;-)

    The reason I prefer whenever over manually editing the crontab is the nice syntax and that I have the definition of the cronjobs in my application. And by using whenever in my deployment script I no longer have to care about the crontab, it is always up-to-date.

  • Boris Barroso

    Nice to see that you are using Ruby, I used to use CakePHP (jeje). I’ve seen this feature on railscasts.com and a really nice feature that you can read in http://asciicasts.com/episodes/164-cron-in-ruby, there you can see a capistrano recipy to automate when you update your cron jobs.

  • cakebaker

    @Boris: Thanks for your comment!

    Yes, that’s a nice capistrano recipe, though, so far I use a simple Git hook script for deployment purposes.

© daniel hofstetter. Licensed under a Creative Commons License