我有一个rails应用程序,我想在后台运行一个作业,但我需要从原始事件开始工作2小时。
用例可能是这样的:
用户发布产品详情。 后台工作排队等候联合列表到第三方api,但即使在原始请求之后,响应可能需要一段时间,第三方的解决方案是每2小时轮询一次,看看我们是否能获得成功确认。
那么有没有办法对作业进行排队,以便工作守护程序知道忽略它或只在预定时间收听它?
我不想使用cron,因为它会加载整个应用程序堆栈,并且可能会在重叠的长时间运行的作业上执行两次。
可以使用优先级队列吗?有什么解决方案来实现这个目标?
答案 0 :(得分: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)
答案 1 :(得分:0)
使用Rufus Scheduler 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 page有更多的例子。