モデルがあるとしましょうEvent。イベントの経過後、招待されたすべてのユーザーに通知(電子メール、プッシュなど)を送信したい。以下の線に沿った何か:
class Event(models.Model):
    start = models.DateTimeField(...)
    end = models.DateTimeField(...)
    invited = models.ManyToManyField(model=User)
    def onEventElapsed(self):
        for user in self.invited:
           my_notification_backend.sendMessage(target=user, message="Event has elapsed")
さて、もちろん、重要な部分はonEventElapsedいつでも呼び出すことtimezone.now() >= event.endです。end現在の日付から数か月先になる可能性があることに注意してください。
私はこれを行う2つの基本的な方法について考えました。
- cron過去5分以内にイベントが経過したかどうかを確認してメソッドを実行する定期的なジョブ(たとえば、5分ごとなど)を使用します。
- 使用し、将来的に実行するパラメーターを使用 - celeryしてスケジュール- onEventElapsedし- etaます(モデル- saveメソッド内)。
オプション1を検討すると、考えられる解決策は次のようになりますdjango-celery-beat。ただし、通知を送信するために一定の間隔でタスクを実行するのは少し奇妙に思えます。さらに、(おそらく)それほど洗練されていない解決策となる(潜在的な)問題を思いつきました。
- 5分ごとに、直前の5分間に経過したイベントを確認しますか?不安定なようですが、いくつかのイベントが見落とされている可能性があります(または他のイベントで通知が2回送信されますか?)潜在的な回避策:True通知が送信されたときに設定されるブール型フィールドをモデルに追加します。
次に、オプション2にも問題があります。
- イベント開始/終了日時が移動した場合は手動で対処してください。を使用する場合celery、taskID(easy、ofc)を保存し、日付が変更されたらタスクを取り消して、新しいタスクを発行する必要があります。しかし、私は、セロリに将来実行されるタスクを処理するときに(デザイン固有の)問題があることを読みました:githubのOpen Issue。これがどのように起こり、なぜそれが解決するのが簡単ではないのかがわかります。
今、私は潜在的に私の問題を解決できるいくつかのライブラリに出会いました:
- celery_longterm_scheduler(しかし、これは、Schederyクラスが異なるため、以前のようにセロリを使用できないことを意味しますか?これは、django-celery-beat... の可能な使用法にもつながります... 2つのフレームワークのいずれかを使用すると、ジョブをキューに入れることができます(実行時間は少し長くなりますが、数か月先ではありませんか?)
- django-apscheduler、を使用しapschedulerます。しかし、遠い将来に実行されるタスクを処理する方法についての情報は見つかりませんでした。
私がこれに取り組む方法に根本的な欠陥はありますか?あなたが持っているかもしれないどんな入力についても嬉しいです。
通知:これは何らかの意見に基づく可能性が高いことを知っていますが、醜いまたはエレガントなものと見なされるものに関係なく、見逃した非常に基本的なことがあるかもしれません。