Я планирую задание работать в 10 минут. Как правильно отменить эту конкретную работу без использования каких-либо грязных дополнительных полей в модели и т.д. Есть ли какой-либо вызов для удаления определенного задания или заданий, связанных с конкретной моделью, экземпляром и т.д.?
Как отменить запланированную работу с delayed_job в Rails?
Ответ 1
отказ от ответственности: я не являюсь опытным пользователем 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
если вам нужно, чтобы какая-то из задач процесса удаляла задания по типу задания, вы могли бы прокручивать каждую из них и удалять ее, если она соответствует вашей задаче; попробуйте в script/console
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"
Таким образом, вы можете быть более избирательным, какие записи удалить?
надеюсь, это даст вам достаточно информации о возможных способах его решения?
Ответ 2
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
)
Ответ 3
Вы можете также рассмотреть возможность использования метода 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]>