假设我有一个模型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")
Run Code Online (Sandbox Code Playgroud)
现在,当然,关键部分是调用onEventElapsedwhen timezone.now() >= event.end。请记住,end距离当前日期可能还有几个月的时间。
我想过两种基本的方法来做到这一点:
使用定期cron作业(例如,每五分钟左右)检查过去五分钟内是否发生了任何事件并执行我的方法。
使用celery和调度onEventElapsed使用eta将来要运行的参数(在模型save方法中)。
考虑选项 1,一个潜在的解决方案可能是django-celery-beat。但是,以固定的时间间隔运行任务以发送通知似乎有点奇怪。此外,我提出了一个(潜在的)问题,它(可能)会导致一个不太优雅的解决方案:
True一旦发送通知。再说一次,选项 2 也有它的问题:
celery,必须存储taskID(easy, ofc) 并在日期更改后撤销任务并发出新任务。但我读过,芹菜在处理将来运行的任务时有(特定于设计的)问题:github 上的 Open Issue。我意识到这是如何发生的,以及为什么要解决这一切都是微不足道的。现在,我遇到了一些可能会解决我的问题的库:
django-celery-beat...的可能用法有关。使用这两个框架中的任何一个,是否仍然可以排队作业(只是运行时间更长但不是几个月?)apscheduler. …我正在为我的大学的一个团队开发一个项目,其中我主要从事前端和一些基本的 django 模型的工作,所以我对 django-celery 不太熟悉和雄辩,而且我也没有设置它。起初我们使用了一名芹菜工人,但我必须再添加一名工人,这样我才能完成一个用户故事。
我目前正在运行两个工作人员,每个工作人员在终端中运行一个,如下所示:
exec celery -A my_proj --concurrency=1 worker
exec celery -A my_proj --concurrency=1 worker -B -Q notification
Run Code Online (Sandbox Code Playgroud)
当我运行这两个项目时,我的项目有效,但我需要它们从一行开始。那么:如何将这两个脚本合并到一行中?
到目前为止我已经尝试过这个:
exec celery multi start celery -A my_proj --concurrency=1 notification -A my_proj --concurrency=1 -B -Q notification
Run Code Online (Sandbox Code Playgroud)
但这使我的项目无法正常运行。
任何帮助表示感谢,谢谢!