gpt4 book ai didi

heroku - 尽管使用锁,Rufus-scheduler 还是调度了两次

转载 作者:行者123 更新时间:2023-12-05 05:14:20 24 4
gpt4 key购买 nike

我很清楚为什么会发生这种情况(两个 ruby​​ 运行时),对于那些之前没有阅读 RS FAQ 或搜索过 SO 的人来说这是一个常见问题,但我花了几天时间尝试许多规定的解决方案,但我的 rufus-scheduler 继续调用两次。

这仅发生在生产环境中,在 Heroku 上运行 Rails 5.0.6,Puma 服务器。

这是我的 scheduler.rb:

require 'rufus-scheduler'

a_scheduler = Rufus::Scheduler.new(:lockfile => ".rufus-scheduler-a.lock")
b_scheduler = Rufus::Scheduler.new(:lockfile => ".rufus-scheduler-b.lock")

unless defined?(Rails::Console) || File.split($0).last == 'rake' || !Rails.env.production?
a_scheduler.cron '0 21 * * *', overlap: false, blocking: true do
MySidekiqWorker.perform_async unless a_scheduler.down?
end

b_scheduler.every '1h', overlap: false, blocking: true do
MyOtherSidekiqWorker.perform_async unless b_scheduler.down?
end
end

我试过锁文件,配置我自己的 scheduler_lock,.every.cron 的不同参数。此外,似乎即使我有 overlap: falseblocking: trueMyOtherSidekiqWorker 的新实例仍然会在一个仍在运行时被调用.

我一定遗漏了一些明显的东西,感谢您的帮助。

最佳答案

所以,Heroku dynos not sharing the file system

在 dyno d0 上看到的 .rufus-scheduler-a.lock 不是在 dyno d1 上看到的 .rufus-scheduler-a.lock

您的 Heroku dynos 不共享相同的文件系统,它们也不共享相同的 Ruby 进程,因此不共享相同的 rufus-scheduler 实例。所以overlap: false, blocking: true不会对dyno d0到dyno d1产生任何影响。

您可以从 https://github.com/jmettraux/rufus-scheduler#advanced-lock-schemes 中获得灵感,为 rufus-scheduler 实现自定义锁定机制。 (可能通过数据库,因为它由您的 Ruby 进程共享)但这对 overlap: falseblocking: true 没有帮助。

如果您仍然想要 overlap: falseblocking: true,您可以查看 https://devcenter.heroku.com/articles/scheduled-jobs-custom-clock-processes并使用 rufus-scheduler 或 Clockwork 在专用进程/dyno 中进行调度,并且不需要调度锁。

我的其余回答是关于您的代码,而不是关于您正在经历的双重调度。

scheduler.down?

b_scheduler.every '1h', overlap: false, blocking: true do
MyOtherSidekiqWorker.perform_async unless b_scheduler.down?
end

为什么你有这个 unless b_scheduler.down? 如果 b_scheduler 挂了,这个 block 根本不会被执行。

这就足够了:

b_scheduler.every '1h', overlap: false, blocking: true do
MyOtherSidekiqWorker.perform_async
end

a_scheduler 与 b_scheduler

您不需要为每项工作安排一个调度程序。你可以简单地写:

require 'rufus-scheduler'                                                   

#scheduler = Rufus::Scheduler.new(lockfile: '.rufus-scheduler.lock')
scheduler = Rufus::Scheduler.new

unless defined?(Rails::Console) || File.split($0).last == 'rake' || !Rails.env.production?
scheduler.cron '0 21 * * *', overlap: false, blocking: true do
MySidekiqWorker.perform_async
end
scheduler.every '1h', overlap: false, blocking: true do
MyOtherSidekiqWorker.perform_async
end
end

关于heroku - 尽管使用锁,Rufus-scheduler 还是调度了两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52659059/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com