【问题标题】:Using timeout in a sidekiq or activejob perform method在 sidekiq 或 activejob 执行方法中使用超时
【发布时间】:2015-08-06 15:01:18
【问题描述】:

我计划从 Heroku Scheduler 转移到使用 Clockwork gem 的自定义时钟进程。如果任务在下一个相同类型的调度任务之前没有完成,Heroku 调度程序将终止该任务。 如何在 Sidekiq 中实现这一点?

鉴于 Timeout 不是线程安全的。在 Sidekiq 工作人员中执行此操作是个坏主意吗?

class RunsTooLongWorker
  include Sidekiq::Worker

  sidekiq_options :retry => false

  def perform(*args)
    Timeout::timeout(2.hours) do
      # do possibly long running task
    end
  end
end

如果没有,还有什么选择?假设我想每 10 分钟运行一次作业,但我不想同时运行相同的作业。我该如何处理?

【问题讨论】:

    标签: ruby concurrency sidekiq rails-activejob


    【解决方案1】:

    回答这部分问题:

    鉴于 Timeout 不是线程安全的。在 Sidekiq 工作人员中执行此操作是个坏主意吗?

    这是 Mike Perham 写的一篇很棒的博客文章 why you shouldn't use Ruby's timeout module in sidekiq jobs

    至于替代方案...听起来您最需要的是确保您的工作不会相互影响。为此,我可以想到两种方法:

    • 穷人的方法:在您正在处理的对象的模型上创建一个“入队”属性。当您开始正在进行的任何处理时,将该项目标记为已入队,完成后将其标记为“未入队”。将你每十分钟的工作范围限定给那些没有排队的人。或者,使用您的作业名称及其状态字段创建一个新表,并在重新执行处理之前查询它的可用性。

    • 如果您要处理更复杂的事情,这听起来像是 Sidekiq Unique Jobs gem. 的绝佳案例。我认为“执行时”方法是您想要的方法。

    【讨论】:

      【解决方案2】:

      我猜你的任务的解决方案是使用 whenever gem,正如 Sidekiq wiki 所建议的那样,这是 wiki for whenever 安装后它将创建 config/schedule.rbfile 你例如,可以定义您的工作时间表

      every 3.hours do
        runner "MyModel.some_process"
        rake "my:rake:task"
        command "/usr/bin/my_great_command"
      end
      

      它具有三种内置类型,您可以从 sn-p runner, rake and command 中看到,但您也可以定义您拥有的,并且在 wiki 中也有说明。

      【讨论】:

      • 我为这个问题添加了更多上下文。我已经在使用发条了,就像任何时候一样。
      猜你喜欢
      • 1970-01-01
      • 2015-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-17
      • 2020-02-18
      • 2016-12-27
      • 2016-03-25
      相关资源
      最近更新 更多