Как php (в частности на Laravel) сайты осуществляют события при наступлении нужных даты/времени?

Здравствуйте!
Понадобилась сейчас реализовать выполнение многих разных задач при наступлении определённых даты/времени (у каждой задачи прописаны эти дата/время) на сайте.
1 тип событий: Пользователи могут включать какие-то события, т.е. жмут кнопку, сервер производит какие-то действия, расчёты, обновляет данные в бд (postgresql) ставя в них дату/время начала и расчитанные дату/время окончания для этого события и этого юзера.
2 тип событий: Уже есть заготовленные события, которые вызываются в определённое время, напр. каждый вторник в 15:15 всем юзерам выдать такое-то сообщение, или определённые данные в бд обновить или ещё что.
Нужно: отслеживать, подошли ли дата/время этих событий; когда подошли - вызвать соответствующий событию метод, обновить данные в бд, если нужно - выдать уведомления одному или нескольким юзерам или запустить ещё какое-то событие, так же отслеживаемое.
Т.е., как я это вижу пока, каждую секунду (либо минуту, пока ещё не решено длительность задач будет кратна секунде или минуте) нужно проверять весь список имеющихся задач и сравнивать их дату/время с наступившим временем на сервере. Если совпало, то выполнить эту задачу.

Как такое реализовывают на сайтах php, в частности на Laravel?
Мне посоветовали очереди с redis, прочитала, но вроде они не позволяют выполнять задачи по времени, а просто одну за другой выполняют. Или это не так и можно настроить их по времени? А если нет, что тогда подходит для решения данного случая? В ларе ещё events есть, может это то, что нужно? Подскажите, пожалуйста. сталкиваюсь с подобным впервые..
Использую Laravel 5.4, postgresql 11.1, xampp - php 7.2.0, apache 2.4.29, windows 10, не продакш, у себя локально делаю.
  • Вопрос задан
  • 1404 просмотра
Решения вопроса 5
Легко )
Стартуют команды Cron'ом
Ответ написан
@Barmunk
Настройте Laravel Task Scheduler на винде и используйте внутренний планировщик, как описано в документации.

Как включить Task Scheduler на win10 https://quantizd.com/how-to-use-laravel-task-sched...
Ответ написан
Helldar
@Helldar
Niemand, außer uns!
Используйте шедулер https://laravel.com/docs/5.8/scheduling
В случае юзерских, выполняя команду https://laravel.com/docs/5.8/artisan пробегаете по юзерам и смотрите у кого "наступило время".
Если точнее, выставить запрос, исключающий лишнее. Например,

$items = App\Page::where('available_at', '<=', now())->get();

Про редиску выше писали - это очереди, там совсем другое и не про то (https://laravel.com/docs/5.8/queues)
Ответ написан
Alixx
@Alixx Автор вопроса
Всем спасибо за ответы.) Всё получилось с планировщиком задач в ларе и винде. Может кому пригодится, опишу подробней:
В бд создать таблицу с задачами (id, date_end с индексом - не позже этого времени нужно выполнить эту задачу, type - тип задачи, и пр.).
В app/Console/Kernel.php создала artisan команду, вызывается ежеминутно
...
 protected $commands = [
        'App\Console\Commands\DateTasksUsers'
    ];
 protected function schedule(Schedule $schedule)
    {
        $schedule->command('date_tasks:users')->everyMinute();
    }
...

В app/Console/Commands/DateTasksUsers.php - файл для команды. В ней проходим таблицу задач, ищем те, время которых уже подошло. Для каждой полученной задачи вызываем соответствующую функцию.
...
    protected $signature = 'date_tasks:users';
    ...  
    public function handle()
    {
        $tasks = TaskUser::where('date_end', '<=', time())
            ->get(); 
        if (!is_null($tasks)) {
            foreach($tasks as $task)
            {
                if ($task->type == 1)
                    User::task_change($task); // там уже проверяем данные, обновляем данные в бд, уведомление кидаем 
                                    // юзеру и т.д. Там же в конце удаляем эту задачу.
                elseif ($task->type == 2)
                    Item::task_upgrade($task);
                // дальше так же добавлять новые типы задач и вызов соответствующих ф-й для них
            }
        }
    }

Настроить планировщик винды (у меня 10ка) как в статье (там для xampp как раз показано), которую скинул Barmunk.
Вот и все манипуляции)
Смущает только то, что задачи выполняются последовательно, а надо бы запустить их все разом параллельно, т.е. в несколько процессов.
Ответ написан
Пригласить эксперта
Ответы на вопрос 4
Не могу сказать точно, что поняла суть вопроса, но если речь идёт о событиях в определённое время, то можно использовать такой вариант:

Вместо проверки точной даты и времени
( " if ($date == ... ) " )
нужно использовать, чтобы дата проверялась как-бы "поверх" нужного значения

То есть, задана, например, дата выполнения задачи 15 сентября в 6:00.
В MySQL записываем это DATETIME вместе, либо в отдельной ячейке год, отдельно час и так далее

Как только Пользователь заходит на сайт, мы сверяем не дату с датой, а если месяц больше указанного месяца, если год больше указанного года и так далее:

// Получаем текущую дату
$Y = date("Y");
$m = date("m");
$d = date("d");

// Из запроса MySQL Select берём дату мероприятия
$event_year = $myrow['year'];
...

if ($event_year < $Y || $event_month < $m || $event_day < $d) {
echo 'Событие "Капитаны" уже проводится/проводилось';
}


Если Вы записывали в MySQL дату целиком, то всё то-же самое, только обрезаем её

$event_date = $myrow['date'];
            
$event_year = substr($event_date, 0, 4);
$event_month = substr($event_date, 5, 2);
$event_day = substr($event_date, 8, 2);


Это НЕ работает:
Если надо высылать уведомление о начале события на Емейл и подобное.

Когда Пользователь заходит на сайт, тогда идёт проверка, но при этом событие появляется.
Чуть покопавшись, можно так-же сделать и конец события
Ответ написан
@potkot
PHP программист
Из комментов понял, что у вас не Linux сервер. Если так, то в windows есть планировщик заданий (и в сервер версии и в обычной). Это то же самое, что крон по факту. Запускает задачи в определенное время с определенной переодичностью.
Ответ написан
@Imrahil
Ну или не тянуть в крон Лару, а воспользоваться например готовым
https://github.com/hutnikau/job-scheduler
Или
https://m.habr.com/ru/post/345802
Ответ написан
xPomaHx
@xPomaHx
1vs9
Если вопрос "как?" теоретический, то вордпрес например имеет свой крон, и на каждый запрос проверяет нужно ли че нибудь запустить, то есть если у вас задача на ночь, а человек тока утром зайдет на главную страницу, то и задача утром запустится.
Такое не сложно и на ларе реализовать если уже не сделано чего то готового.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
Amigoweb Магнитогорск
от 50 000 до 70 000 руб.
Ready for Sky Санкт-Петербург
от 110 000 до 120 000 руб.
18 апр. 2019, в 20:45
750 руб./в час
18 апр. 2019, в 20:33
300 руб./за проект
18 апр. 2019, в 20:27
50000 руб./за проект