假设我有模型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
可能离当前日期还有几个月的时间。
我已经考虑了两种基本的方法:
使用定期的cron
作业(例如,每五分钟左右),该作业检查在最近五分钟内是否发生了任何事件并执行我的方法。
使用celery
并使用onEventElapsed
参数计划eta
将来运行(在模型save
方法内。
考虑选项1,可能的解决方案可能是django-celery-beat
。但是,以固定的时间间隔运行任务以发送通知似乎有些奇怪。另外,我想出了一个(潜在的)问题,(可能)会导致一个不太优雅的解决方案:
True
。 然后,选项2也有问题:
celery
时,一旦日期更改并发出新任务,就必须存储taskID
(easy,ofc)并撤销任务。但是我已经读到,在处理将来运行的任务时,芹菜存在(特定于设计的)问题:Open Issue on github。我意识到这是如何发生的,为什么它只是解决所有问题而已。 现在,我遇到了一些可以潜在地解决我的问题的库:
django-celery-beat
的可能用法联系在一起...使用两个框架中的任何一个,是吗?仍然可以对作业进行排队(它们的运行时间更长一些,但是还没有几个月?)apscheduler
。但是,我找不到任何有关如何处理在不久的将来运行的任务的信息。我处理此问题的方式是否存在根本的缺陷?我很高兴收到您的任何意见。
[[注意:我知道这可能是基于某种观点的,但是,也许有一些我很想念的东西,不管某些人认为它是丑陋还是优雅。
具有每小时运行的cron /芹菜节拍,以检查是否需要发送任何通知。然后发送这些通知并将其标记为完成。这样,即使您的通知时间提前了几年,它仍将被发送。使用ETA并不是等待时间很长的方法,您的缓存/ amqp可能会丢失数据。
您可以根据需要缩短时间间隔,但请确保它们不会重叠。
如果一个小时的时差太大,那么您可以做的就是每小时运行一个调度程序。逻辑将类似于