Итак, Heroku dynos не разделяет файловую систему
.rufus-scheduler-a.lock
, видимый на dyno d0, не .rufus-scheduler-a.lock
, видимый на dyno d1.
ВашДинозавры Heroku не используют одну и ту же файловую систему, а также они не используют один и тот же процесс Ruby и, следовательно, не один и тот же экземпляр rufus-scheduler.Так что overlap: false
, blocking: true
не будет иметь никакого эффекта от dyno d0 до dyno d1.
Вы можете реализовать собственный механизм блокировки для rufus-планировщика, получая вдохновение от https://github.com/jmettraux/rufus-scheduler#advanced-lock-schemes (возможно, черезбазы данных, потому что она используется вашими процессами Ruby), но это не поможет с overlap: false
и blocking: true
.
Если вы все еще хотите иметь overlap: false
и blocking: true
, вы можете посмотреть на https://devcenter.heroku.com/articles/scheduled-jobs-custom-clock-processes и планирование происходит в выделенном процессе / dyno с помощью rufus-scheduler или Clockwork и не нуждается в блокировке расписания.
Остальная часть моего ответа о вашем коде, а не о двойном планированиивы испытываете.
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
не работает, блок не будет выполненвообще.
Этого достаточно:
b_scheduler.every '1h', overlap: false, blocking: true do
MyOtherSidekiqWorker.perform_async
end
a_scheduler vs 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