2010-09-03 1 views
35

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

ответ

49

отказа от ответственности: Я не эксперт пользователя 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" 

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

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

+1

Идеальное решение! – mdrozdziel

+10

Возможно, вы должны использовать «destroy» вместо «delete». –

+1

Мертвые удобны, спасибо за действительно подробный ответ. + –

7

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

Я бы действительно не рекомендовал делать так. «Режиссер» предназначен для масштабирования приложения. Вы уже прошли через пользовательский Struct, просто выберите другое имя атрибута house9. – Dex

Смежные вопросы