Предположим, у меня есть модель Event
. Я хочу отправить уведомление (по электронной почте, pu sh, что угодно) всем приглашенным пользователям, как только событие пройдет. Что-то вроде:
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
может быть через несколько месяцев от текущей даты.
Я думал о двух основных c способах сделать это:
Использовать periodi c cron
задание (скажем, каждые пять минут или около того), которое проверяет, произошли ли какие-либо события в течение последних пяти минут, и выполняет мой метод.
Использование celery
и запланируйте onEventElapsed
, используя параметр eta
для запуска в будущем (в рамках метода save
).
С учетом варианта 1, потенциальное решение может быть django-celery-beat
. Тем не менее, кажется немного странным запускать задачу с фиксированным интервалом для отправки уведомлений. Кроме того, у меня возникла (потенциальная) проблема, которая может (вероятно) привести к не очень элегантному решению:
- Проверять каждые пять минут на события, которые произошли в предыдущие пять минут? кажется шатким, может быть, некоторые события пропущены (или другие получают свои уведомления дважды?). Возможное решение: добавьте логическое поле в модель, для которого установлено значение
True
после отправки уведомлений.
Опять же, у варианта 2 также есть свои проблемы:
- Вручную позаботьтесь о ситуации, когда перемещается дата / время начала / окончания события. При использовании
celery
нужно будет сохранить taskID
(easy, из c) и отозвать задачу, как только даты будут изменены, и выпустить новую задачу. Но я читал, что у сельдерея есть (design-speci c) проблемы при работе с задачами, которые будут выполняться в будущем: Open Issue на github . Я понимаю, как это происходит и почему это все, но тривиально, чтобы решить.
Теперь я столкнулся с некоторыми библиотеками, которые потенциально могут решить мою проблему:
- celery_longterm_scheduler (Но значит ли это, что я не могу использовать сельдерей как Я хотел бы иметь раньше, из-за другого класса планировщика? Это также связано с возможным использованием
django-celery-beat
... Используя любую из двух структур, все еще возможно поставить в очередь задания (которые только немного дольше выполняются, но не прошло и месяца?) - django -apscheduler , использует
apscheduler
. Однако я не смог найти никакой информации о том, как он будет обрабатывать задачи, выполняемые в далеком будущем .
Есть ли какой-то фундаментальный недостаток в том, как я к этому подхожу? Я рад любым вашим комментариям.
Примечание: я знаю, что это, вероятно, Тем не менее, некоторые из них основаны на мнении, может быть, есть кое-что из базового c, которое я пропустил, независимо от того, что некоторые считают уродливым или изящным.