Задать вопрос
@uniquerichboy

Вопрос по Laravel queue, как сделать чтоб очереди выполнялись друг за другом и не пересекались?

У меня от 500-2000 очередей который запускаются в разное время на неделю вперёд и когда-то могут вызваться в одно время и превысить лимит запросов сервиса к которому обращаюсь, моя задача к которой я не могу найти решения кроме громких Kafka и RabbitMq, но и то не сильно уверен что мне нужны такие сервисы, искал готовые решения на гите, ничего не нашел, читал про Haystak, не то, Spatie тоже не то, тупо выкидывает задачи, но лимиты соблюдает, а мне надо чтоб они друг за дружкой шли, 1 задача выполняется, остальные ждут хоть и должны выполниться в данный момент, но найти решения не смог, надеюсь здесь найду решение!
  • Вопрос задан
  • 1032 просмотра
Подписаться 2 Простой 5 комментариев
Пригласить эксперта
Ответы на вопрос 3
pLavrenov
@pLavrenov
Разработка сайтов
В коробке есть WithoutOverlapping, добавь туда "ключ" группы необходимых задач и они будут выполняться по очереди.
Ответ написан
Комментировать
agoalofalife
@agoalofalife
Team Lead
Поделюсь опытом, готового решения в Laravel из коробки нет.
Если надо остаться в рамках Laravel то есть несколько вариантов. Можно допилить функционал в самом Laravel, но код внутри не готов к такой кастомизации. (говорю заранее это будет жесткий костыль, он будет мешать нормальной работе очередей). Второй вариант, сделать еще одну базовую очередь.
Что я имею в виду?
Вариант №1
Мы берем простой кэш или redis(сразу) с его очередью(вроде это lists) , и добавляем туда наши jobs, каждый раз когда когда job выполняется, она смотрит должна ли именно она сейчас выполниться и если нет, то скрипт ее возвращает обратно в обычную очередь.
Соответственно запуск job регулируется другой очередью(то есть вы организуете добавление jobs в обычную очередь), из минусов, ваши jobs будут туда сюда гоняться скриптом и полезной работы не какой. Если например один уйдет в fail jobs - worker будет гонять туда сюда пока вы не выполните его и не восстановиться работа.

Вариант №2
Второй вариант сделать уже нормальную базовую очередь. К примеру, делаете таблицу в базе данных. Когда job в нормальном flow должен отправляться в очередь, вы отправляете его в эту таблицу. Дальше вы пишите своего демона(worker) который просматривает вашу таблицу на предмет выполнения.
Если что то готово выполняться, он отправляет его в обычную очередь. Добавляете в эту таблицу статусы и вперед.
Job добавилась в таблицу - "ready"
Job ушла - "в процессе"
Job выполнилась - "удалилась из таблицы или approved"
Возможно еще есть колонки для группировки(например принадлежность какой нибудь группе), теперь ваш демон может запускать их по очереди даже в рамках групп.
Соответственно все идут друг за другом, пока один "в процессе" остальные не берутся.
Ответ написан
@vrusua
Для более сложных сценариев, где недостаточно WithoutOverlapping и нужен контроль выполнения, можно взять одно из решений стейт-машины (или конечных автоматов) под Laravel, либо создать свой велосипед, как предложили выше.

См. Laravel Workflow - оркестратор задач на базе Laravel jobs и UI тузла Waterline к нему для мониторинга выполнения:
https://github.com/laravel-workflow/laravel-workflow
https://github.com/laravel-workflow/waterline

Также еще альтернативы:
https://github.com/zerodahero/laravel-workflow
https://github.com/sebdesign/laravel-state-machine
https://github.com/asantibanez/laravel-eloquent-st...
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Похожие вопросы