Thursday, March 15, 2012

Make scheduled jobs in heroku safer for your wallet.

I recently checked my current usage on Heroku to find that I had used a much higher than expected number of dyno-hours. The project is a RC aviation website that provides some weather data. The forecast data is pulled every hour via FTP by a rake task that is run with a scheduled job in Heroku. Normally this takes around a minute to run and uses about 13 or 14 dyno-hours in a month. Less than half way through this month I found that it had already burned through over 200 dyno-hours.

After digging into the problem I found that the FTP connection was hanging for some reason. After a little research I came up with a solution that works pretty nicely and for more than just hanging FTP connections.

It turns out that ruby's standard library includes a library named Timeout which provides a way to terminate the execution of a thread. Using this library it is very simple to set a time limit for a block of code in a rake test.

task :task_that_takes_a_long_time_sometimes do
  Timeout.timeout(30) do
    #The code that takes a long time to run sometimes

That will raise a Timeout::Error if the code takes longer than 30 seconds to run. The error will cause the rake task to exit, preventing unexpected dyno-hour usage.