我正在安排一个任务,在大约10分钟后运行。如何正确取消这个特定的任务,而不使用任何脏字段在模型中等等。是否有调用来删除特定任务或与特定模型、实例相关的任务?
我要安排一个任务,在10分钟后运行。如果想要取消这个任务,没有必要在模型中添加额外的脏字段等。是否有调用可以删除特定任务或与特定模型、实例相关的任务呢?请保留原文中的html标签。我正在安排一个任务,在大约10分钟后运行。如何正确取消这个特定的任务,而不使用任何脏字段在模型中等等。是否有调用来删除特定任务或与特定模型、实例相关的任务?
我要安排一个任务,在10分钟后运行。如果想要取消这个任务,没有必要在模型中添加额外的脏字段等。是否有调用可以删除特定任务或与特定模型、实例相关的任务呢?请保留原文中的html标签。免责声明:我不是延迟任务(delayed_job)的专家...
"是否有任何调用可以删除特定的工作,或与特定模型、实例等相关的工作?"
Delayed::Job只是一个ActiveRecord对象,因此您可以查找和销毁其中的任何记录。根据您的使用情况,这可能以不同的方式处理。如果有人要手动销毁它们,则可以通过Web应用程序中的管理员界面处理。
# 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'时才这样做。在这种情况下,您可能需要在MyJob对象上实现“display_name”。如果存在,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"
这样你就可以更有选择性地删除记录了?
希望这为你提供了足够的信息来处理它的可能方法?
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
)
queue
旨在使应用程序具有可扩展性。您已经使用自定义结构体完成了操作,只需选择一个不同的属性名称,就像house9所做的那样。 - DexDelayed::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]>
我认为循环遍历所有排队的作业序列化字段(:handler)可能会变得昂贵,特别是当队列很大时(例如当Rails事件存储库重放您订阅以安排作业的事件时)。
因此,对我来说似乎有效的解决方案是避免手术,看起来像这样:
# some_specific_event_handler.rb or policy
record_uuid = SomeModel.find(event.data[:id]).uuid
queue_name = "#{record_uuid}_update_notification"
Delayed::Job.where(queue: queue_name).destroy_all
UpdateNotificationJob.set(
wait: 30.minutes,
queue: queue_name,
).perform_later(record_uuid)
Delayed::Job 是一个 Delayed::Backend::ActiveRecord
:queue 字段只是一个字符串。 我认为它的值并不影响工作何时以及如何执行,除非您的代码对其进行了某些操作。
所以我将我的应用逻辑钩入到 :queue 字段值中,并且它适用于我的情况,其中,根据要求:
Delayed::Job.all.each do |job|
。(需要 .each)。 - Vox