2017-01-07 16 views
3

私は、Herokuが少なくとも1日に1回はdynosを再起動することを前提に、Clockwork、Sidekiq、およびRedisがどのように一緒になっているかについて少し混乱しています。Herokuで毎日実行するように作業者をスケジュールすると、それが2回実行されない、またはスキップされることをどのように確認できますか?

が、それは次のように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 

のは、誰かが月曜日にサインアップするとしましょう、この仕事は、水曜日に実行される、それらを見つけ、それらを第二確認メールを送信します。その後、何らかの理由でdynoが再起動し、ジョブが再び実行されます。彼らはまだ別の電子メールを得るでしょう。あるいは、ジョブが実行される前に再起動が発生した場合、何も取得されません。

HerokuDynoの「寿命」を考えれば、Clockworkは24時間以上のジョブの概念をどのように持っていますか?このようなことをデータベースに絶えず保存しなくても、この制限を単純に管理する方法はありますか?

答えて

1

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

+0

これは可能な限り最良の回答です。 – rdegges

0

IMOこのような問題を回避するには、データベースにさらに情報が必要です。状態マシンが助けてもよいし、明示的な列であってもよい。あなたはこのようなあなたの仕事でクエリを書くことができるようになる

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

それが複数回日を実行した場合、クエリはもう気にしない、または日以降の偶然。

+0

ええ、本当にこれを避けたかったのは、これが最初の1〜2週間にわたってメールを送信することが何度もあるからです。状態機械はそれをより良くするが、依然として相当量の作業を行うだろう。うーん。 –

+0

データベースの無駄なスペースが心配ですか?ほとんど予備の列を持つことについて?私はこの列をより詳細な統計を可能にするため、良いものとして見ています。マーケティングとBIは、電子メールの利点をよりよく理解するために、そのような列を増やしたいと考えています。 – spickermann

関連する問題