2012-05-15 46 views
0

我想在非常精确的时间运行一个进程。现在我正在使用延迟作业:简单查询:如何在Rails中精确安排工作?

handle_asynchronously :make_live, :run_at => (exact_time_down_to_the_second) 

但它并不准确。例如,当我这样做时:

handle_asynchronously :make_live, :run_at => (Time.now + 30.seconds) 

......它在30秒钟+/- 15秒内执行。随后的尝试发生在Time.now左右的6秒钟内,有时几乎立即发生。

是否有确切的方法来做到这一点?不要拖延工作。

编辑

当我这样做:

handle_asynchronously :make_live, :run_at => Proc.new {|event| event.occurs_at } 

...它运作良好,(似乎对队列的查询精确到秒)。即使使用短时间间隔(30秒)。

它看起来像只是控制台测试工作不好。

这样就解决了我现在的问题。

回答

0

延迟可能是由两个因素造成的:延迟作业定期检查作业。延迟作业也会按顺序执行作业,所以如果队列中已经有一些作业,它会延迟。

如果您知道并且可以提前定义任务(即与当前时间不相关),请使用Whenever宝石,它是cronjobs的包装。

为Delayedjobs创建一个单独的队列还可以减少长队列造成的延迟。

你也可以切换到Resque,这就像内存中的队列,它可能会以较短的时间间隔检查队列。

+0

我会检查出每当。顺便说一句,我只在队列中测试一项工作;应用程序本身永远不会超过4个,间隔一天左右。 – bevanb

0

好的。你的工作包装对你来说不够精确。我看到2个选项:

  1. 替换或修改作业包装更加精确。 Resque可能会有所帮助,或者您可以在Delayed :: Job内部戳一下以更频繁地轮询工作。可以,但我更喜欢这种攻击:
  2. 安排工作60秒之前,当你需要它运行。作为参数传递您需要执行作业的确切时间。然后,运行sleep until Time.now == exact_time_down_to_the_second

热潮!精确的执行,直到第二个。

+0

另外,lulalala提出了一个很好的观点:如果你在这之前排队工作,Delayed :: Job可能仍然无法及时赶到工作。这听起来像是你的应用将现在的工作分开了,但是在将来,如果你有其他类型的工作,你会希望有一个这样的重要任务的队列,并将其他工作放在一个单独的队列中单独的工作者池。 我相信Delayed :: Job现在支持命名队列,或者Resque肯定会。祝你好运! – nthj

+0

如果您的查询长度很长,会发生什么情况?所有工人都会睡觉,查询会增长。这是一个非常糟糕的主意。 –

+0

应该睡在适当实施我的解决方案的唯一工人是工作人员运行这一关键工作。为了安全起见,您可以将作业封装在超时模块中,或者相应地调整MAX_RUN_TIME。 – nthj

0

默认情况下,延迟作业设置为每5秒轮询数据库。你可以调整这个,让它每秒轮询一次。我对需要这种精度级别的用例感到好奇。也许有更好的解决方案?