Delayed_Job: доступ к метаданным задания и / или избежание дублирования заданий - PullRequest
9 голосов
/ 27 июля 2011

Я пытаюсь получить дату и время выполнения в пользовательском классе. мой код выглядит так:

class MyCustomJob < Struct.new(:my_object)

  def perform
    if self.run_at == my_object.start_time
      # process the job
    end
  end

end

Я тоже попробовал Delayed::Job.find(self), но не повезло.

заранее спасибо

Ответы [ 2 ]

11 голосов
/ 24 июня 2013

Если вы определите метод before для своего пользовательского задания, работник передаст вам экземпляр отложенного задания перед вызовом execute:

class MyCustomTask

  def before(job)
    @job = job
  end

  def perform
    # has access to @job object. 
    # You may need to call @job.reload to see in-flight changes to object in the database.
  end
end
8 голосов
/ 27 июля 2011

Вы должны справиться с этим при создании задания:

   priority = 0
   run_time = my_object.start_time
   Delayed::Job.enqueue(MyCustomJob.new(my_object), priority, run_time)

https://github.com/tobi/delayed_job/wiki

Если ваши задания не выполняются в ожидаемое время, возможно, вы планируете их на UTC:

http://www.gregbenedict.com/2009/08/19/is-delayed-job-run_at-datetime-giving-you-fits/

Чтобы проверить очередь на существующее задание - вы можете сделать следующее:


class MyCustomJob < Struct.new(:object_id)

  def self.exists?(object_id)
    Delayed::Job.where(['handler = ? and failed_at is null',handler(object_id)]).count(:all) > 0
  end

  def self.handler(object_id)
    "--- !ruby/struct:MyCustomJob \nobject_id: #{object_id}\n"
  end

  def perform
    my_object = MyObject.find(object_id)
    my_object.do_stuff
  end
end

Тогда просто проверьте MyCustomJob.exists?(my_object.id) перед очередью.

Это немного взломать - отредактируйте метод handler по мере необходимости. Я бы изменил таблицу delayed_jobs, чтобы иметь класс / object_id для более чистого кода и более эффективного сканирования таблиц, если ваша таблица заданий большая или вы делаете это с другими типами заданий.

Этот вопрос также выглядит актуально:

Как отменить запланированное задание с delayed_job в Rails?

...