2

我正在构建一个客户培育应用程序,当订单满足某些基于时间的条件时,它将发送一封电子邮件,例如:

  • 50% OF Order time_to_ship elapsed
  • 10 DAYS AFTER Order ship_date
  • 5 DAYS AFTER NewsletterSubscriber signup_date

我正在尝试确定如何最好地触发处理这些事件。我没有处理此问题的经验,因此感谢您提供任何意见。

当前想法:轮询每个处理程序的匹配项,并确保每个处理程序匹配组合仅通过一个额外的表触发一次。在这种情况下,我不会触发可以在其他地方收听的事件,每个处理程序都在执行自己的查询。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,或者不会跳过一个事件(比如跳过 20% 的事件,因为停机时间)。与已触发但感觉更像真正的事件发射器的记录处理程序相比,这将存储数千条记录。

4

2 回答 2

5

Django async 是一个异步执行队列。您可以安排未来的事件,然后检查该条件当时是否有效。例如,当订单发货时,安排一个在 10 天后触发的事件,当它执行时,它可以在发送电子邮件之前确定任何其他条件。

http://pypi.python.org/pypi/django-async/

Django async 已内置运行一次行为,如果队列因任何原因停止,它将在重新启动时赶上过去的作业。暂时性错误(如 SMTP 服务器关闭)将自动重试。

于 2012-07-12T03:23:06.523 回答
0

我会创建一个 django 管理命令来执行您需要的任何处理,然后分配一个 cronjob 来定期执行它。

然后,您可能需要一个模型来跟踪是否满足/处理了条件,和/或哪些记录触发了事件。

于 2012-07-12T03:19:44.923 回答