3
votes

I use whenever to call rake tasks throughout the day, but each task launches a new Rails environment. How can I run tasks throughout the day without relaunching Rails for each job?

Here's what I came up with, would love to get some feedback on this...?

  1. Refactor each rake task to instead be a method within the appropriate Model.

  2. Use the delayed_job gem to assign low priority and ensure these methods run asynchronously.

  3. Instruct whenever to call each Model.method instead of calling the rake task

Does this solution make sense? Will it help avoid launching a new Rails environment for each job? .. or is there a better way to do this?

--

Running Rails 3

3

3 Answers

4
votes

You could certainly look into enqueuing delayed_jobs via cron, then having one long running delayed_job worker.

Then you could use whenever to help you create the delayed_job enqueuing methods. It's probably easiest to have whenever's cron output call a small wrapper script which loads active_record and delayed_job directly rather than your whole rails stack. http://snippets.aktagon.com/snippets/257-How-to-use-ActiveRecord-without-Rails

You might also like to look into clockwork.rb, which is a long-running process that would do the same thing you're using cron for (enqueuing delayed_jobs): http://rubydoc.info/gems/clockwork/0.2.3/frames

You could also just try using a requeuing strategy in your delayed_jobs: https://gist.github.com/704047

0
votes

Lots of good solutions to this problem, the one I eventually ended up integrating is as such:

  1. Moved my rake code to the appropriate models
  2. Added controller/routing code for calling models methods from the browser
  3. Configured cronjobs using the whenever gem to run command 'curl mywebsite.com/model#method'

I tried giving delayed_job a go but didn't like the idea of running another Rails instance. My methods are not too server intensive, and the above solution allows me to utilize the already-running Rails environment.

0
votes

Comment this line from schedule.rb

require File.expand_path(File.dirname(__FILE__) + "/environment")

Instead load only required ruby files like models in your case.