Huw*_*Huw 5 activerecord ruby-on-rails heroku delayed-job
我有一种感觉,这在 Rails 中相当于疑病症……但我看了一眼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 *
Run Code Online (Sandbox Code Playgroud)
它每五秒运行一次。那么...呃,这是...正常吗?
我突然想到,这就是延迟作业必须工作的方式,通过根据时间戳检查作业,所以这就是它的作用,但我未能找到合适的书面证据来证明这一点。
如果是这样......我的第二个问题是这不会在我的 Heroku 实例上烧钱吗?我安装了workless gem以试图降低成本 - 但我没有看到任何代码来关闭它......
Bug 或功能,我怎样才能不让自己破产?
我会尽力比其他人更完整地回答你的问题。
是的,这是正常行为。当您启动延迟作业流程时,它会按照可配置的时间间隔检查数据库中是否有未处理的作业。(默认值为每 5 秒一次,您可以使用Delayed::Worker.sleep_delay设置将其配置为不同的间隔。)
您是对的,在其中一次定期检查期间,延迟作业会检查下一个需要完成的可用作业,然后运行它。
为了有效地运行延迟作业,您通常需要始终打开工作测功机来不断检查要运行的新作业。
然而,您在问题中链接到的无用的宝石可以帮助您解决这个问题。Workless 不需要让工作人员 24/7 来检查新工作,而是仅在队列中有工作要运行时才启动工作人员 dyno。当工作完成后,workless 会关闭worker dyno。
您可以在 workless 的 README 中阅读此行为的描述:
无业是如何运作的?
Delayed::Workless::Scaler混合到Delayed::Job类中,这会向其中添加一堆回调。- 当在数据库上创建作业时,创建回调会启动一个工作线程。
- 工作人员运行该作业,并将其从数据库中删除。
- 销毁回调会停止工作线程。
然而,总有一个权衡。Heroku 启动一个工人测功机需要时间,因此新工作的处理不会那么即时。例如,对于持续运行的worker dyno,您的作业通常会在 5 秒内运行。如果您使用 Workless,则测功机启动和延迟作业可能需要大约 30 秒才能完成作业。显然,什么是可接受的取决于您的应用程序,因此这完全由您决定。