延迟作业ActiveRecord ::作业加载 - 每5秒运行一次?

时间:2016-08-26 12:56:56

标签: ruby-on-rails activerecord heroku delayed-job

我感觉这是Rails相当于hypochondria ...但是我看了tail -f logs/development.log然后被输出催眠了:

  Delayed::Backend::ActiveRecord::Job Load (0.8ms)  UPDATE "delayed_jobs" SET locked_at = '2016-08-26 12:49:09.594888', locked_by = 'host:ghost pid:4564' WHERE id IN (SELECT  "delayed_jobs"."id" FROM "delayed_jobs" WHERE ((run_at <= '2016-08-26 12:49:09.594275' AND (locked_at IS NULL OR locked_at < '2016-08-26 08:49:09.594332') OR locked_by = 'host:ghost pid:4564') AND failed_at IS NULL) ORDER BY priority ASC, run_at ASC LIMIT 1 FOR UPDATE) RETURNING *
  Delayed::Backend::ActiveRecord::Job Load (0.5ms)  UPDATE "delayed_jobs" SET locked_at = '2016-08-26 12:49:14.651262', locked_by = 'host:ghost pid:4564' WHERE id IN (SELECT  "delayed_jobs"."id" FROM "delayed_jobs" WHERE ((run_at <= '2016-08-26 12:49:14.650707' AND (locked_at IS NULL OR locked_at < '2016-08-26 08:49:14.650765') OR locked_by = 'host:ghost pid:4564') AND failed_at IS NULL) ORDER BY priority ASC, run_at ASC LIMIT 1 FOR UPDATE) RETURNING *
  Delayed::Backend::ActiveRecord::Job Load (0.5ms)  UPDATE "delayed_jobs" SET locked_at = '2016-08-26 12:49:19.716179', locked_by = 'host:ghost pid:4564' WHERE id IN (SELECT  "delayed_jobs"."id" FROM "delayed_jobs" WHERE ((run_at <= '2016-08-26 12:49:19.715433' AND (locked_at IS NULL OR locked_at < '2016-08-26 08:49:19.715494') OR locked_by = 'host:ghost pid:4564') AND failed_at IS NULL) ORDER BY priority ASC, run_at ASC LIMIT 1 FOR UPDATE) RETURNING *

每隔五秒运行一次。所以......呃,那......正常吗?

我发现这是延迟工作必须工作的方式,通过检查作业的时间戳,所以这就是它做的事情,但我找不到合适的书面证据。

如果是这样的话......我的第二个担忧是不会在我的Heroku实例上烧钱吗?我已经安装了workless gem来试图降低成本 - 但是我没有看到任何代码进来关闭它......

错误或功能,我怎么不破产自己?

3 个答案:

答案 0 :(得分:3)

这确实是工作延迟的原因。默认sleep_delay为5秒(Source Code)。

您可以按照here概述在初始值设定项中配置自定义延迟。寻找sleep_delay

答案 1 :(得分:2)

我会尽力比其他人更完整地回答你的问题。

是的,这是正常行为。启动延迟作业进程时,它会以可配置的时间间隔检查数据库中的未处理作业。 (默认值为每5秒,您可以使用Delayed::Worker.sleep_delay设置将其配置为不同的时间间隔。)

你是正确的,在其中一次定期检查中,延迟作业检查下一个需要完成的可用作业,然后再运行它。

要有效地运行延迟工作,您通常会始终使用工作人员dyno来持续检查要运行的新工作。

但是,您在问题中链接到的无用宝石可以帮助您解决这个问题。而不需要让工作人员每周7天每天24小时检查新工作,只有当队列中有作业运行时,无法工作才会启动工作人员。当工作完成后,无法工作的人关闭了工作人员。

您可以在无工作的自述文件中阅读description of this behavior

  

Workless如何工作?

     
      
  • Delayed::Workless::Scaler混合到Delayed::Job类中,这会为它添加一堆回调。
  •   
  • 在数据库上创建作业时,创建回调会启动工作程序。
  •   
  • 工作人员运行该作业,将其从数据库中删除。
  •   
  • 销毁回调会阻止工作人员。
  •   
然而,总会有一个权衡。 Heroku需要时间来启动工作人员dyno,因此新工作的处理不会立即进行。例如,对于经常运行的工作人员,你的工作通常会在5秒内完成。如果您使用无工作,则可能需要大约30秒才能启动dyno并使延迟作业能够完成工作。显然,可接受的取决于你的申请,所以这完全是你的决定。

答案 2 :(得分:0)

添加以下行并根据需要更改频率。

#initializers/delayed_job_config.rb
Delayed::Worker.sleep_delay = 60 #for a 60 second sleep time.