Is Delayed Job :run_at => DateTime Giving You Fits?

I’ve been implementing Delayed Job to poll Twitter every minute for changes. However, it was immediately running everything and ignoring the run_at time in the database. Or so I thought.

Upon inspection of the code for Delayed Job, it is polling the database time to UTC and not local time.

def self.db_time_now
      (ActiveRecord::Base.default_timezone == :utc) ? Time.now.utc : Time.now
end

What was

Delayed::Job.enqueue PollTwitter.new(), 0, 1.minutes.from_now

has now become

Delayed::Job.enqueue PollTwitter.new(), 0, 1.minutes.from_now.getutc

Four hours is a large difference.

Note: Normally I would just run this as a cron job, but Heroku will only run cron once per hour.

3 Responses to “Is Delayed Job :run_at => DateTime Giving You Fits?”

  1. Hi Greg,

    I’m also trying to get heroku to run a task every minute. Could you tell me how you populated the delayed jobs table so that there was a task for every minute?

    Many thanks,
    Graeme

  2. Graeme,

    There are two steps that I do. The first is I create a rake task that adds the job to the queue.

    Delayed::Job.enqueue MyStruct.new()

    The second step is that I add a similar call at the bottom of the MyStruct perform() method.

    Delayed::Job.enqueue MyStruct.new(), 0, 1.minute.from_now.getutc

    Now this isn’t programmatically ideal because it creates a new record every minute. But in practice, you won’t max out an 11 digit integer field in the next 100 years.

  3. Christian says:

    I went with this strategy and forgot to set DJ’s maximum-attempts. It went out of controll with awful many jobs going bananas during the night due to an exception raised in each job:) I guess there are some trix to avoid this, delete other jobs before queue the next. Never run more then once. etc. I ended up with a solution where hourly cron schedules jobs for the next 12 hours, and maintain the job-queue and sees to that all jobs are present. So cron checks that there always are 720 jobs present, one for each minute.. Not a good solution eighter I think, a long queue for a simple task. Another strategy I found usefull is to setup a remote crontab doing curl against a middelware-url in my app on Heroku every minute.

Leave a Reply