如何在一个月的特定日期范围内创建幂等工作?
How to create idempotent jobs on specific period of day range of month?
我的应用程序中有很多工作具有以下条件:
- 每月需要执行一次操作,而且只能执行一次
- 需要在特定日期执行操作(例如:月底前 10 天)
- 作业每天会重新运行多次,所以它们必须是幂等的,可以重新运行多次并且只影响特定的记录,直到下个月如果所有记录可以再次生效
想想月底前 5 天通过短信发送的付款提醒。
我可以想出很多方法来做到这一点,但老实说,我尝试的每一种方法最终都会因不同的时间减法、.where() 子句等而变得非常混乱
我真的在寻找一个已知的 设计模式 或一些防弹逻辑,它不是令人困惑的时间减法、大于、小于和令人困惑的面条式混乱查看(并且容易出现错误)
这是我最好的尝试。不过,请随时从头开始帮助我……它不必修改它。我觉得这比它需要的要复杂得多。
class SMSPaymentReminderJob < Que::Job
@priority = 50
def run
current = Time.now.in_time_zone('America/New_York')
window_end = current.end_of_month
window_start = window_end.beginning_of_day - 2.days
cutoff = current.beginning_of_month.utc # convert to UTC for PG
return unless (window_start..window_end).cover? current
User.where(sms_enabled: true)
.where('"sms_reminder_sent_at" < ? OR "sms_reminder_sent_at" IS NULL', cutoff)
.find_in_batches(batch_size: 30) do |users|
# ... code here ...
end
end
end
GUI 的 IceCube (to handle recurring events) and maybe RecurringSelect 组合将实现这一点,同时考虑到 ease-of-use 并允许扩展。
然后您可以设置您的活动,例如:
IceCube::Rule.monthly
IceCube::Rule.monthly.day_of_month(-10)
我的应用程序中有很多工作具有以下条件:
- 每月需要执行一次操作,而且只能执行一次
- 需要在特定日期执行操作(例如:月底前 10 天)
- 作业每天会重新运行多次,所以它们必须是幂等的,可以重新运行多次并且只影响特定的记录,直到下个月如果所有记录可以再次生效
想想月底前 5 天通过短信发送的付款提醒。
我可以想出很多方法来做到这一点,但老实说,我尝试的每一种方法最终都会因不同的时间减法、.where() 子句等而变得非常混乱
我真的在寻找一个已知的 设计模式 或一些防弹逻辑,它不是令人困惑的时间减法、大于、小于和令人困惑的面条式混乱查看(并且容易出现错误)
这是我最好的尝试。不过,请随时从头开始帮助我……它不必修改它。我觉得这比它需要的要复杂得多。
class SMSPaymentReminderJob < Que::Job
@priority = 50
def run
current = Time.now.in_time_zone('America/New_York')
window_end = current.end_of_month
window_start = window_end.beginning_of_day - 2.days
cutoff = current.beginning_of_month.utc # convert to UTC for PG
return unless (window_start..window_end).cover? current
User.where(sms_enabled: true)
.where('"sms_reminder_sent_at" < ? OR "sms_reminder_sent_at" IS NULL', cutoff)
.find_in_batches(batch_size: 30) do |users|
# ... code here ...
end
end
end
GUI 的 IceCube (to handle recurring events) and maybe RecurringSelect 组合将实现这一点,同时考虑到 ease-of-use 并允许扩展。
然后您可以设置您的活动,例如:
IceCube::Rule.monthly
IceCube::Rule.monthly.day_of_month(-10)