次のような注文で時間ベースの条件が満たされたときにメールを送信する顧客育成アプリケーションを構築しています。
50% OF Order time_to_ship elapsed
10 DAYS AFTER Order ship_date
5 DAYS AFTER NewsletterSubscriber signup_date
これらのイベントを最適に起動して処理する方法を決定しようとしています。私はこの問題を扱った経験がないので、どんな意見でも歓迎します。
現在のアイデア: 各ハンドラーの一致をポーリングし、各ハンドラーと一致するコンボが追加のテーブルを介して 1 回だけ起動するようにします。この場合、他の場所でリッスンできるイベントを発生させることはなく、各ハンドラーが独自のクエリを実行します。3 つのハンドラー5 days after ...
が 3 つのクエリを起動します。
# build table that stores which handlers have fired for a given object
class HandlerFired(models.Model):
ctype = models.ForeignKey(ContentType, related_name="handlerfired_ctype")
id = models.IntegerField()
handler = models.ForeignKey(Handler)
class Handler(models.Model):
ctype = models.ForeignKey(ContentType)
condition = ...
# cron job every day
for handler in Handler.objects.filter(is_active=True):
objects = handler.run_query().exclude(
handlerfired=handler, handlerfired_ctype=handler.ctype)
handler.handle(objects) # do whatever it's supposed to do with given objects.
# handle() would also make sure the `HandlerFired` table is populated with a record.
このアイデアは、プロジェクトを開始したときに想像していたよりも少し多くの悲しみ/オプションを与えてくれました. 時間主導のイベントを持つことは、かなり一般的な問題のように思えます。
または、ハンドラーではなくイベントの毎日の cron ジョブを実行することもできますが、発生したすべてのイベントを追跡して、2 を発生させないようにするか、1 つがスキップされないようにする必要があると思います (たとえば、20% のイベントがスキップされたため、ダウンタイム)。これにより、発生したハンドラーを記録するよりも数千のレコードが保存されますが、実際のイベント エミッターのように感じられます。