3

Heroku が少なくとも 1 日に 1 回は dyno を再起動することを考えると、Clockwork、Sidekiq、および Redis がすべて Heroku にどのように適合するかについて、私は少し混乱しています。

1 日に 1 回実行されるワーカーがあるとします。そのため、次のように構成されconfig/clock.rbています。

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

このワーカーでは、アカウントを作成したが 2 日以内に確認していないすべてのユーザーを取得し、各ユーザーに確認メールを再送信します。

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

誰かが月曜日にサインアップし、このジョブが水曜日に実行され、彼らを見つけて、2 番目の確認メールを送信するとします。その後、何らかの理由で dyno が再起動され、ジョブが再び実行されます。彼らはさらに別の電子メールを受け取ります。または、ジョブの実行が必要になる直前に再起動が行われた場合、何も得られません。

Heroku dyno での「寿命」を考えると、Clockwork には 24 時間より長いジョブの概念があるのはなぜですか? この種のものをデータベースに常に保存することなく、この制限を簡単に管理する方法はありますか?

4

2 に答える 2

1

毎週水曜日に実行することがわかっている場合は、Heroku スケジューラ ( https://devcenter.heroku.com/articles/scheduler ) を使用することをお勧めします。設定した時間間隔で特定のコマンドを実行できます。複雑さが少ない。

于 2017-01-07T07:17:17.747 に答える
0

このような問題を回避したい場合は、データベースにさらに情報が必要です。ステート マシンまたは明示的な列が役立つ場合がありsecond_confirmation_send_atます。

これにより、次のようにジョブにクエリを記述できます。

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

その後、クエリが 1 日に複数回実行されても、1 日後に偶然実行されても、クエリは気にしなくなります。

于 2017-01-07T08:34:24.770 に答える