Предположим, у меня есть модель Event
. Я хочу отправить уведомление (электронная почта, push, что угодно) всем приглашенным пользователям после того, как событие прошло. Что-то вроде:
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) и отозвать задачу, как только даты изменились, и выпустить новую задачу. Но я читал, что у сельдерея есть (специфичные для дизайна) проблемы при работе с задачами, которые будут выполняться в будущем: Открытая проблема на github . Я понимаю, как это происходит и почему это все, но тривиально, чтобы решить.
Теперь я столкнулся с некоторыми библиотеками, которые потенциально могут решить мою проблему:
- celery_longterm_scheduler (Но значит ли это, что я не могу использовать celery, как раньше, из-за другого класса Scheduler? Это также связано с возможным использованием
django-celery-beat
... При использовании любой из двух структур все еще можно ставить в очередь задания (что только немного дольше, но не через несколько месяцев?) - Джанго-Апшедулер , использует
apscheduler
. Тем не менее, я не смог найти никакой информации о том, как он будет обрабатывать задачи, которые выполняются в далеком будущем.
Есть ли какой-то фундаментальный недостаток в том, как я к этому подхожу? Я рад за любой вклад, который вы могли бы иметь.
Обратите внимание: я знаю, что, скорее всего, это будет основано на некотором мнении, но, может быть, есть одна очень простая вещь, которую я пропустил, независимо от того, что некоторые могут считать уродливыми или изящными.