0

我想在一个非常精确的时间运行一个进程。现在我正在使用延迟工作:

handle_asynchronously :make_live, :run_at => (exact_time_down_to_the_second)

但它根本不精确。例如,当我这样做时:

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

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

有没有一种精确的方法来做到这一点?没有卡在延迟的工作上。

编辑

当我做:

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

...它运作良好(似乎将队列轮询到第二个)。即使使用短间隔(30 秒)。

看起来只是控制台测试效果不佳。

所以这解决了我现在的问题。

4

3 回答 3

0

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

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

繁荣!精确执行,精确到秒。

于 2012-05-15T05:52:57.623 回答
0

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

如果您知道并且可以提前定义任务(即与当前时间无关),请使用作为cronjobs的包装器的 When gem。

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

您还可以切换到Resque,它类似于内存队列,它可能会以较短的间隔检查队列。

于 2012-05-15T05:33:36.313 回答
0

默认情况下,延迟作业设置为每 5 秒轮询一次数据库。您可以调整它,使其每秒轮询一次。我很好奇需要这种精度水平的用例。也许有更好的解决方案?

于 2012-05-29T18:33:44.933 回答