Do you write rails apps? Have you ever wanted to automate rake tasks with cron? Easy peasy, right? Well, its not that hard for the most part, but there are some issues to think about:
- What happens if you try to re-deploy your rails app while your cronned tasks are running?
- What happens if you migrate your database while a long-running cron is processing?
- What happens if you get the cron syntax wrong? Ever have a script start every second when it should run once a day?
- Ever have a cron task start before the previous one had completed?
- Ever try to find your cronned task's log intermixed with your controller log entries?
- Ever want to change your cron entries, and think its ugly that everything else about your deploy is automated?
Wouldn't it be great to solve all these issues with one gem? Crondonkulous!
install the gem:
gem sources -a http://gems.github.com
gem install bokmann-crondonkulous
in your rails app, generate the files:
./script/generate crondonkulous
The generate will give you some further instructions - in a nutshell:
- add
require 'crondonkulous/recipes'to the top of your deploy.rb cap file - add
config.gem "lockfile"to your environment.rb - uncomment whatever cron entries you want to run in the generated config/crontab.erb file
- write your periodic tasks where it says 'your code here' in the
lib/tasks/crondonkulous.rakefile
Pretty easy, right?
What you get:
- a lib/tasks/crondonkulous.rake file that you add your code to. Stubbed out tasks include every_minute, every_5_minutes, every_15_minutes, every_hour, every_day, every_week, and every_month.
- a config/ctontab.erb file that gets rendered and put into the cron table. This file already includes the proper syntax for tasks that run every minute, every 5 minutes, every 15 minutes, hourly, daily, weekly, and monthly.
- conventions for naming/logging. Each periodic task gets its own log file, like
log/every_minute.log - protection via the LockFile gem. crondonkulous rake tasks won't run at the same time (unless you let them), and will wait/retry to run the number of times you specify.
- Capistrano integration to remove the old cron entries while deploying and insert new cron entries before application restart
Motivation
A while back I wrote the 'Automate Repeatable Tasks' recipe (#72) for the 'Advanced Rails Recipes' book. Those ideas, and more, are embodied in this gem. In particular, the management of entries into the cron tab is a lot easier. I have done this for various apps time and time again, and wanted to promote some common conventions.
Extras
Crondonkulous inserts the crontab entries into the user doing the deployment by default. When I have total control over the hosting environment, I prefer to create a user specifically for the application and install the cron entries there. you can add:
set :cron_user, "my_app_user"
to your deploy.rb if you want to do the same.
You can follow the project on github.
Have fun!
How does this compare to the Whenever gem? It looks like there are some differences, but it has the same basic idea behind it. What motivated you to build this over using that?
http://github.com/javan/whenever/tree/master
Posted by: Ryan Bates | August 28, 2009 at 11:04 AM
The whenever gem looks fantastic - I love their dsl for scheduling.
This work predates that gem, and frankly, I didn't know it existed... This is an extraction from a few real-world projects we have been working on for years. I bundled it up for our own use so we'd have consistency between them, and thought it worthy of sharing.
While I like whenever's DSL, I like this gem's use of lockfile, the logging conventions, and the removal of the tasks before the deploy continues. I'm not a fan of the crontab surgery whenever is doing - I did the same kind of thing in my recipe in 'Advanced Rails Recipes', and I have seen that fail in odd ways.
Posted by: David Bock | September 01, 2009 at 09:49 AM