簡體   English   中英

如果我安排一名工人每天在Heroku上運行,我怎么能確定它不會運行兩次或被跳過?

[英]If I schedule a worker to run every day on Heroku, how can I be sure it doesn't run twice or get skipped?

鑒於Heroku每天至少重啟一次dynos,我覺得Clockwork,Sidekiq和Redis如何在Heroku上完全融合,我有點困惑。

假設我有一個每天運行一次的工作者,所以它在config/clock.rbconfig/clock.rb為:

module Clockwork
  every(1.day, 'Resend confirmation') { ResendConfirmationWorker.perform_async }
end

在此工作人員中,我獲得了創建帳戶但尚未在兩天內確認帳戶的所有用戶,並向每個帳戶重新發送確認電子郵件。

class ResendConfirmationWorker
  include Sidekiq::Worker
  sidekiq_options queue: :resend_confirmation, retry: false

  def perform
    d = Time.zone.now - 2.days
    users = User.where.not(confirmation_sent_at: nil)
                .where(confirmed_at: nil)
                .where(created_at: d.beginning_of_day..d.end_of_day)

    users.find_each do |user|
      user.send_confirmation_instructions
    end
  end
end

假設有人在星期一報到,這個工作在周三運行,找到他們,並向他們發送第二封確認電子郵件。 然后dyno因任何原因重新啟動,並且作業再次運行。 他們會收到另一封電子郵件。 或者,如果重新啟動發生在作業需要運行之前的那一刻,那么它們將無法獲得任何結果。

鑒於其在Heroku dyno中的“壽命”,發條如何有超過24小時的任何工作概念? 有沒有辦法簡單地管理這個限制,而不必經常將這種東西保存到數據庫?

如果你知道你將在每個星期三執行它,我建議使用Heroku Scheduler( https://devcenter.heroku.com/articles/scheduler )。 它允許您以設定的時間間隔運行特定命令。 減少復雜性。

IMO如果要避免此類問題,則需要在數據庫中獲取更多信息。 狀態機可能有幫助或顯式second_confirmation_send_at列。

這將允許您在工作中編寫查詢,如下所示:

users = User.where('confirmation_sent_at < ?', 2.days.ago)
            .where(second_confirmation_send_at: nil)

如果它一天運行多次,或者一天后意外運行,則查詢不再關心。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM