使用Sidekiq,有哪些策略可以让它在每个时区的特定时间执行?
例如,我需要Sidekiq在世界各地以下时间和时区每天执行任务:
...
美国东部时间晚上8:00
美国中部时间晚上8:00
美国山区时间晚上8:00
美国太平洋时间晚上8:00
...
使用Sidekiq,有哪些策略可以让它在每个时区的特定时间执行?
例如,我需要Sidekiq在世界各地以下时间和时区每天执行任务:
...
美国东部时间晚上8:00
美国中部时间晚上8:00
美国山区时间晚上8:00
美国太平洋时间晚上8:00
...
我会在每个小时的开头运行同样的工作。您可能希望使用cron每小时运行该作业,或查看此列表以了解如何在Sidekiq中创建定期作业。
作业中的第一步是找出当前时间为上午8点
的所有时区:
8am_time_zones = ActiveSupport::TimeZone.all
.select { |tz| tz.now.hour == 8 }
.map { |tz| tz.tzinfo.name }
#=> ["America/Los_Angeles", "America/Tijuana", "America/Phoenix"]
使用此列表,您可以轻松地从数据库中加载生活在某个时区(假设您以此格式存储用户的时区)的用户,并向他们发送电子邮件:
User.where(time_zone: 8am_time_zones).find_each do |user|
# email_newsletter(recipient: user)
end
创建这个任务并且每1小时1分钟执行一次
class ScheduleBasedOnTimeZoneJob < ApplicationJob
queue_as :default
def perform
# only execute in the beggening if the day
return unless now.to_i - now.beginning_of_day.to_i < 300
time_zones = ["America/Los_Angeles", "America/Tijuana", "America/Phoenix"]
time_zones.each do |time_zone|
now = Time.now.in_time_zone(time_zone)
# Schedule job at 08:00 AM based on the provided timezone
schedule_at = now.change(hour: 8, min: 0)
MyTzBasedJob.set(wait_until: schedule_at).perform_later(time_zone: time_zone)
end
end
end
Sidekiq没有针对“每天”这种用例的调度机制。您需要像whenever这样的cron调度程序。
假设您的服务器已配置为UTC,您只需创建您的计划:
# EST 8pm
every 1.day, :at => '1:00 am' do
runner "MyModel.task_to_run_at_1_am_UTC"
end
# CST 8pm
every 1.day, :at => '2:00 am' do
runner "MyOtherModel.task_to_run_at_2_am_UTC"
end
要在一行代码中完成:
every '* 6,7,8,9,10 1 * *' do
runner "MyOtherModel.task_to_run_at_2_am_UTC"
end
看一下cron语法的构成方式。
MyModel.task_1
)。使用whenever
gem是否可以实现这一点? - Chad Taylor