Ruby-on-rails 如何在 Rails 中使用 delay_job 取消预定作业?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3638250/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 23:08:58  来源:igfitidea点击:

How to cancel scheduled job with delayed_job in Rails?

ruby-on-railsrubyruby-on-rails-3delayed-job

提问by mdrozdziel

I am scheduling a job to run in say, 10 minutes. How to properly cancel this particular job without using any kind of dirty extra fields in model and so on. Is there any call to remove particular job, or jobs related to specific model, instance, etc?

我正在安排一个工作,比如 10 分钟。如何在不使用模型中任何类型的脏额外字段的情况下正确取消此特定作业等。是否有任何要求删除特定作业或与特定模型、实例等相关的作业?

回答by house9

disclaimer: I am not an expert user of delayed_job...

免责声明:我不是 delay_job 的专家用户...

"Is there any call to remove particular job, or jobs related to specific model, instance, etc?"

是否有任何要求删除特定作业,或与特定模型、实例等相关的作业?

Delayed::Job is just an ActiveRecord object so you can find and destroy any of those records. Depending on your use case this could be handled different ways. If someone is going to manually destroy them this could be handled through an admin interface in your web app.

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

if you need some out of process task deleting jobs by 'job type' you could loop through each one and delete it if it matches your job; try this in 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"

so given the above if you wanted to delete all jobs of type MyJob

因此,如果您想删除 MyJob 类型的所有作业,请参考上述内容

Delayed::Job.all.each do |job|
    if job.name == "MyJob" then
        job.delete
    end
end

this may or may not help for your situation? in many cases you might want to delete a MyJob but only where the :some_value attribute was 'abc' and not 'xyz'. In this case you might need to implement a 'display_name' on your MyJob object. job.name will use this if it exists

这对您的情况可能有帮助,也可能无济于事?在许多情况下,您可能想要删除 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"

this way you could be more selective about which records to delete?

这样你就可以更有选择性地删除哪些记录?

hopefully this gives you enough information on possible ways to handle it?

希望这可以为您提供有关处理它的可能方法的足够信息?

回答by firien

delayed_job 3 introduced a queueattribute. This can be hiHymaned to schedule a cancelable job.

delay_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
)

回答by fitchMitch

You may also consider using delayed job's payload_object method, if you're looking for a job through its passed parameter only.

如果您仅通过其传递的参数寻找工作,您也可以考虑使用延迟工作的 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

This simplist example do not use fully the payload_object returned:

这个简单的例子没有完全使用返回的payload_object:

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