Как отменить запланированную работу с delayed_job в Rails? - PullRequest
36 голосов
/ 03 сентября 2010

Я планирую выполнить задание, скажем, через 10 минут.Как правильно отменить эту конкретную работу без использования каких-либо грязных дополнительных полей в модели и так далее.Есть ли какие-либо призывы удалить конкретную работу или работы, связанные с конкретной моделью, экземпляром и т. Д.?

Ответы [ 3 ]

50 голосов
/ 04 сентября 2010

отказ от ответственности: я не опытный пользователь delayed_job ...

" Есть ли какие-либо вызовы для удаления конкретного задания или заданий, связанных с конкретной моделью, экземпляром и т. Д.? "

Delayed :: Job - это просто объект ActiveRecord, поэтому вы можете найти и уничтожить любую из этих записей. В зависимости от вашего варианта использования это может быть обработано различными способами. Если кто-то собирается уничтожить их вручную, это можно сделать через интерфейс администратора в вашем веб-приложении.

# list all jobs
Delayed::Job.all
# find a job by id
job = Delayed::Job.find(params[:id])
# delete it
job.delete

если вам нужна какая-то внеплановая задача, удаляющая задания по «типу задания», вы можете просмотреть каждую из них и удалить ее, если она соответствует вашей работе; попробуйте это в скрипте / консоли

class MyJob < Struct.new(:some_value);
    def perform
        # ...
    end
end

my_job = MyJob.new('xyz')
job = Delayed::Job.enqueue(my_job, 0, 1.hour.from_now)
job.name
# => "MyJob"
job.handler
# => "--- !ruby/struct:MyJob \nsome_value: xyz\n"

, поэтому, если вы хотите удалить все задания типа MyJob

, вы должны были
Delayed::Job.all.each do |job|
    if job.name == "MyJob" then
        job.delete
    end
end

это может или не может помочь в вашей ситуации? во многих случаях вы можете захотеть удалить MyJob, но только там, где атрибутом: some_value было 'abc', а не 'xyz'. В этом случае вам может понадобиться реализовать 'display_name' в вашем объекте MyJob. job.name будет использовать это, если оно существует

class MyJob < Struct.new(:user_id);
    def perform
        # ...
    end

    def display_name
        return "MyJob-User-#{user_id}"
    end 
end

# store reference to a User
my_job = MyJob.new(User.first.id) # users.id is 1
job = Delayed::Job.enqueue(my_job, 0, 1.hour.from_now)
job.name
# => "MyJob-User-1"
job.handler
# => "--- !ruby/struct:MyJob \nuser_id: 1\n"

таким образом, вы можете более избирательно выбирать, какие записи удалять?

надеюсь, это даст вам достаточно информации о возможных способах справиться с этим?

7 голосов
/ 27 сентября 2013

delayed_job 3 ввел атрибут queue.Это может быть использовано для планирования отменяемой работы.

class MyJob < Struct.new(:user_id)
  def self.queue_name
    "something-unique"
  end

  def perform
    # ...
  end
end

#scheduler
my_job = MyJob.new(User.first.id)
#'cancel' pending jobs first
Delayed::Job.where(queue: my_job.class.queue_name).destroy_all
#queue it up
Delayed::Job.enqueue(my_job,
  queue: my_job.class.queue_name,
  run_at: 1.hour.from_now
)
0 голосов
/ 13 января 2019

Вы можете также рассмотреть возможность использования метода payload_object отложенного задания, если вы ищете задание только по его переданному параметру.

Delayed::Job.all.each do |job|
  job.destroy if job_corresponds_to_target?(job, target)
end

def job_corresponds_to_target?(job, target)
  job.payload_object.args.first == target.id
end

В этом простом примере не полностью используется возвращаемый payload_object:

=> #<Delayed::PerformableMethod:0x0056551eae3660 @object=ReminderMailJob, @method_name=:perform_later, @args=[3]> 

...