Всем привет. Подскажите, как лучше решить такую задачу. К приложению Laravel приходят хуки от стороннего сервиса, каждый хук надо обработать и используя его данные сделать запрос к стороннему апи в такой же хронологии, в которой они к нам пришли. Была идея использовать цепочки заданий, но хуки могут приходить с временным интервалом в несколько секунд и как их тогда запихнуть в одну цепочку - не очень понятно. Также возникает еще одна проблема, т.к. каждый хук обрабатывается за n кол-во времени, то хуки, которые пришли позже, но имеют меньшее время обработки, могут обгонять хуки, которые пришли раньше, но обрабатываются дольше. Т.е. будет нарушена хронология. Как лучше решить такую проблему?
Пусть хук записывает всю необходимую информацию и, главное, время в специальную таблицу в базе данных. Это всё, что будет делать хук. Таким образом он будет работать всегда быстро и всегда за одно и то же очень малое время.
Далее по крону или каким-то другим образом совершенно другой скрипт будет выбирать самую старую запись из этой таблицы и обрабатывать её, совершая необходимые действия. Далее эту запись либо удаляем либо помечаем обработанной и берём следующую запись
Rsa97, тогда, по сути, преимуществ мы никаких не получаем, в виде параллельной обработки нескольких задач. Но тут видимо, либо очередность, либо скорость работы)
Rsa97, Я просто не специалист в Laravel, больше по Symfony. Поэтому и описал универсальную идею, используя базу данных как очередь, потому что с базой данных даже начинающие умеют работать.
В Symfony есть компонент Messenger, который всё это берет на себя, умеет делать очереди как из базы данных, так и в брокерах.
Наверняка, в Laravel есть подобный инструмент
tmgrr, Тут всё зависит от того, что вы делаете в обработчике.
Если, например, запросы во внешние API не требуют очередности, а требует очередности только обработка их конечного результата после этих запросов, то можно добавить конкурентности...
В этой же таблице с данными можно добавить поле result, в которое складывать данные от внешних запросов. Тогда можно будет запустить много обработчиков параллельно.
И уже напоследок ввести ещё один обработчик, который будет только единственным, и который будет из этой таблицы выбирать самую старую запись, смотреть, есть ли данные в поле result.
Если данные есть, то обработать и пометить запись окончательно обработанной или удалить её. А если данных в поле result нет, то ждать пока они там не появятся.
Таким образом мы ускорим общую работу всей обработки в целом, т.к. самые долгие операции - это вызовы внешних API, и именно их мы будем обрабатывать параллельно, а готовый результат будет обрабатываться строго по очереди
Создайте отдельную очередь, в обработчике хука кладите туда задание и обрабатывайте её в один поток.
Т.е. примерно то, что описал Виктор Кожухарь, только готовыми средствами фреймворка.