3

我有一个 Rails 应用程序,我想在后台运行作业,但我需要在原始事件后 2 小时运行作业。

用例可能是这样的:

用户发布产品列表。后台作业排队以将列表联合到第 3 方 api,但即使在原始请求之后,响应也可能需要一段时间,第 3 方的解决方案是每 2 小时轮询一次,看看我们是否可以获得成功确认。

那么有没有办法将作业排队,以便工作守护进程知道忽略它或只在预定时间收听它?

我不想使用 cron,因为它会加载整个应用程序堆栈,并且可能会在重叠的长时间运行的作业上执行两次。

可以为此使用优先级队列吗?有什么解决方案来实现这一点?

4

2 回答 2

2

尝试延迟工作 - https://github.com/collectiveidea/delayed_job

这些方面的东西?

class ProductCheckSyndicateResponseJob < Struct.new(:product_id)
  def perform
    product = Product.find(product_id)

    if product.still_needs_syndicate_response
      # do it ...

      # still no response, check again in two hours
      Delayed::Job.enqueue(ProductCheckSyndicateResponseJob.new(product.id), :run_at => 2.hours.from_now)
    else
      # nothing to do ...
    end
  end
end

第一次在控制器中初始化作业,或者在模型上初始化 before_create 回调?

Delayed::Job.enqueue(ProductCheckSyndicateResponseJob.new(@product.id), :run_at => 2.hours.from_now)
于 2013-06-15T22:15:01.930 回答
0

使用Rufus 调度器 gem。它作为后台线程运行,因此您不必再次加载整个应用程序堆栈。将它添加到您的 Gemfile 中,然后您的代码就像这样简单:

# in an initializer,
SCHEDULER = Rufus::Scheduler.start_new

# then wherever you want in your Rails app,
SCHEDULER.in('2h') do
  # whatever code you want to run in 2 hours
end

github 页面有大量示例。

于 2013-06-15T20:24:23.273 回答