Русское сообщество разработки на PHP-фреймворке Laravel.
Ты не вошёл. Вход тут.
Здравствуйте!
Подскажите, каким образом можно реализовать серверные события по времени? Нужно выполнять много разных задач при наступлении определённых даты/времени (у каждой задачи прописаны эти дата/время).
Если более подробно, то:
1. Пользователи могут включать какие-то события, т.е. жмут кнопку, сервер производит какие-то действия, расчёты, обновляет данные в бд (postgresql) ставя в них дату/время начала и расчитанные дату/время окончания для этого события и этого юзера.
2. Уже есть заготовленные события, которые вызываются в определённое время, напр. каждый вторник в 15:15 всем юзерам выдать такое-то сообщение, или определённые данные в бд обновить или ещё что.
Нужно: отслеживать, подошли ли дата/время этих событий; когда подошли - вызвать соответствующий событию метод, обновить
данные в бд, если нужно - выдать уведомления одному или нескольким юзерам или запустить ещё какое-то событие, так же отслеживаемое.
Т.е., как я это вижу пока, каждую секунду (либо минуту, пока ещё не решено длительность задач будет кратна секунде или минуте) нужно проверять весь список имеющихся задач и сравнивать их дату/время с наступившим временем на сервере. Если совпало, то выполнить эту задачу.
Мне посоветовали очереди с redis, прочитала, но вроде они не позволяют выполнять задачи по времени, а просто выполняют задачи одну за другой. Или это не так? Что тогда подходит для решения данного случая?
P.S.: использую Laravel 5.4, postgresql 11.1, xampp - php 7.2.0, apache 2.4.29, windows 10.
Изменено taraks (21.03.2019 17:55:34)
Не в сети
Т.к. это форум по Laravel, логично использовать расписание и команды. Просто расписание не подходит потому что рассчитано на рерулярные, а не разовые события. Придется сделать чуть хитрее:
Расписание + таблица заданий (at datetime, command varchar(100), arguments text)
Создайте консольную команду, которая будет выполняться ежеминутно. Пусть эта команда делает запрос в таблице заланий и, если у задания указана подходящая дата-время, то вызывает другие команды по имени из той же таблицы заданий.
There are two hard things in computer science: cache invalidation, naming things, and off-by-one errors.
Не в сети
Спасибо! Идея интересная, смущает только способ хранения и выбора задач -
Пусть эта команда делает запрос в таблице заданий
задачи могут часами висеть в ожидании, соответственно, их там накопится...уйма. Каждую минуту дёргать всю таблицу на сотни тысяч записей и проверять в них даты - хорошая ли практика?
таблица заданий (at datetime, command varchar(100), arguments text)
(и, кстати, ключ-то составной будет, id ещё нужен, т.к. at datetime может быть один и тот же у нескольких задач. Либо не составной, а первичный - id, а at datetime - просто индекс)
Изменено taraks (22.03.2019 22:01:37)
Не в сети
Подозреваю, что сама полезная работа длится куда дольше, чем поиск актуальных заданий. Не надо преждевременно оптимизировать
There are two hard things in computer science: cache invalidation, naming things, and off-by-one errors.
Не в сети
(и, кстати, ключ-то составной будет, id ещё нужен, т.к. at datetime может быть один и тот же у нескольких задач. Либо не составной, а первичный - id, а at datetime - просто индекс)
Не вижу здесь потребности в уникальном ключе. А, сталобыть, и в составном.
Ради бога, пусть на одно время запланировано более одной задачи, помоему это нормально. Впрочем, вам контекст виднее, я только базовую идею подал.
There are two hard things in computer science: cache invalidation, naming things, and off-by-one errors.
Не в сети
Получилось всё настроить + планировщик винды. Но! Один момент остался - если задач несколько на одно и то же время - их же надо запустить разом и параллельно в несколько процессов, а пока что в команде, которая делает запрос на подошедшие по времени задачи, в цикле для каждой найденной задачи вызывается соответствующая функция. А как же их запускать параллельно в одно время?
Не в сети