How to create a rake cron job in Heroku
A few weeks ago I had to deal with setting up a cron job that periodically updated some db tables of a Ruby on Rails application running on Heroku. Here’s a brief step-by-step tutorial to make your life easier in case you were approaching the same task.
Go to the “tasks” folder of your application and create a file called “scheduler.rake”. Below you can find an example of a rake task:
[code language=”ruby”]
desc ‘my job description’
task :my_scheduler_job, :from_date do |t, args|
# setup the db connection
require ‘pg’
db_parts = ENV[‘DATABASE_URL’].split(/\/|:|@/)
username = db_parts[3]
password = db_parts[4]
host = db_parts[5]
db = db_parts[7]
conn = PGconn.open(:host => host, :dbname => db, :user=> username, :password=> password)
# read input param
from_date = args[:from_date]
if from_date
date_clause = ‘ AND date > ‘ + from_date
else
date_clause = ”
end
# function that retrieves updated data
updated_data = get_updated_data()
updated_data.each{ |row|
my_query = ‘UPDATE MY_TABLE SET MY_FIELD = #{ row.my_field } WHERE ID = #{ row.id } ‘ + date_clause
begin
conn.exec(sql)
puts ‘Updating id: #{ row.id }’
rescue Exception => e
puts e.message
puts e.backtrace.inspect
puts ‘There was an insert error on #{ index.to_s } in #{ my_query }’
end
}
end
[/code]
Once your task is ready, go to your Heroku application and add the Heroku Scheduler add-on. Now go to the add-on dashboard and add your task by typing
[code]
rake my_scheduler_job
[/code]
and set the desired frequency.
For debugging purposes, it’s possible to run your task from the command line by executing
[code]
heroku run rake my_scheduler_job[‘2013/05/01’]
[/code]
To check that the updates in your database were correctly executed, Heroku provides you a postgres console that can be accessed with the command
[code]
heroku pg:psql DATABASE_URL
[/code]
Hope this tutorial will help you saving some time when having to create rake tasks in Heroku. As always, don’t hesitate writing your feedbacks/questions in the comment section below.