Long running rake tasks on heroku

Heroku puts a limit on how long you can run a process for which means that long running rake tasks will be killed before they complete. The recommended solution is that any long running processes should be run in the background as delayed jobs. This means writing some wrapper code to run your rake task as a delayed job. After doing this a few too many times I went looking for a generic solution.

The solution I arrived at lets you queue up any rake task by prefixing the task name with delay: e.g.

$ rake db:seed
becomesĀ 
$ rake delay:db:seed
rake db:seed will now be run in the background using one of your delayed_job dynos.
The code for this was suprisingly simple. First a job class to hold the rake task.
module DelayedTask
  class PerformableTask < Struct.new(:task)
    def perform
      system "rake #{task}"
    end
  end
end

We then need to define a delayed rake task for each of the existing rake tasks

Rake::Task.tasks.each do |task|
  task "delay:#{task.name}" do
    Rake::Task["environment"].invoke
    Delayed::Job.enqueue DelayedTask::PerformableTask.new(task.name)    
    puts "Enqueued job: rake #{task.name}"
  end
end

I'm now using this on several projects so I've packaged it up into a gem. You can find it at https://github.com/opsb/delayed_task.