Laravel по-русски

Русское сообщество разработки на PHP-фреймворке Laravel.

Ты не вошёл. Вход тут.

#26 Re: Laravel 5.x » Отсутствует задержка при выполнении задачи (Job) из очереди (Queue) » 04.04.2017 09:47:22

constb пишет:

мне кажется ты просто от очередей хочешь странного, они предназначены для того чтобы просто в фоне выполнять задачи, а не для какой-то хитрой логики с ограничением количества выполняемых задач по времени. мне кажется что требуемый функционал специфичен для конкретных типов задач и не должен применяться глобально на уровне целой очереди

обрати внимание на трейт Illuminate\Queue\InteractsWithQueue – он в установке по умолчанию уже присутствует во всех задачах, у него есть метод release() который позволяет на произвольное количество секунд отложить выполнение задачи. ты можешь проверять время последнего обращения к API и релизить задачу на некое случайное количество секунд, если с последнего обращения прошло недостаточно времени. сначала все задачи будут релизиться но достаточно быстро раскидаются по очереди из-за рандома. естественно порядок их выполнения будет тоже случаен, но частота обращения к API не будет превышать требуемую, даже если очередь будет параллельно обрабатываться несколькими процессами-воркерами

ещё один плюс такого решения в том что ты сможешь использовать очередь параллельно для других задач. если задача делает sleep() на несколько секунд – она блокирует очередь. релизнутые задачи очередь не блокируют и она может использоваться другими задачами свободно. если хранить счётчик времени последнего обращения к API где-нибудь в мемкэше или редисе, оно ещё и не будет нагружать систему в процессе его опроса

Насчет специфичности и хитрой логики - могу поспорить, т.к. очередь чаще всего как раз и используется для того, чтобы:
а) не выполнять задачи в фоне, пока юзер ждет ответ
б) не делать кучу действий за раз и выполнять их последовательно (именно в этом варианте я и ожидаю использование задержек, т.к. ранее работал с такими же задачами, но в других экосистемах (python))

Про release() - спасибо, думал о нем, но смущает то, что я не понимаю как задача будет возвращаться в очередь и будет ли это считаться за попытку выполнения (attempt), т.к. она может уходить из очереди допустим, каждый раз, а выполниться ей придется через 10 запусков.
Из-за такого можно словить "пропажу" задач из очереди, а делать attempts=999999 тоже нет никакого желания...

#27 Re: Laravel 5.x » Отсутствует задержка при выполнении задачи (Job) из очереди (Queue) » 04.04.2017 09:09:50

Lord_Alfred пишет:

Пока что буду использовать первый вариант и запускать queue:work через shedule:run, но меня не устраивает данный метод, т.к. будут постоянные перезапуски команды, что не круто, т.к. рано или поздно это начнет забивать память (GC где-то не отработает), плюс к этому мне нужно запускать 50 задач (Job) в сутки, а придется запускать queue:work постоянно, чтобы он не пропустил задачи.

Поясню дополнительно почему не нравится этот вариант: очередь - это очередь, а не запуск команды по cron-задаче. Хочется, чтобы висел какой-то один процесс и постоянно слушал новые задачи для себя. Если делать так, как я поступил сейчас, то вообщем-то и очередь не нужна в том понимании, котором она есть. Просто запускать по крону задачи и всё. Это не красивый вариант, который хочется поменять. Поэтому третий описанный мной способ - более интересен для реализации у себя.

#28 Re: Laravel 5.x » Отсутствует задержка при выполнении задачи (Job) из очереди (Queue) » 04.04.2017 08:47:06

Придумал несколько способов решения свой проблемы:


1. Использовать параметр --once для queue:work, чтобы запускать по 1 задаче в запуск команды.
2. Сделать дополнительное поле runned_at в модели, где лежат API-ключи и перезапускать задачу, если нет ключей, удовлетворяющих условию runned_at < (текущее время - 1 минута).
3. Пронаследовать queue:work и переопределить получение задач: сделать, чтоб он получал задачи не пачкой, а по одной и между получением следующей задачи выполнял задержку в delay секунд

Пока что буду использовать первый вариант и запускать queue:work через shedule:run, но меня не устраивает данный метод, т.к. будут постоянные перезапуски команды, что не круто, т.к. рано или поздно это начнет забивать память (GC где-то не отработает), плюс к этому мне нужно запускать 50 задач (Job) в сутки, а придется запускать queue:work постоянно, чтобы он не пропустил задачи.

Поэтому ваши предложения приветствуются. Если вы считаете, что третий вариант самый "православный" - объясните, пожалуйста, от чего пронаследоваться, а то я бегло поискав эту команду в дебрях лары - не понял от чего пронаследоваться и где переопределять.

#29 Re: Laravel 5.x » Отсутствует задержка при выполнении задачи (Job) из очереди (Queue) » 04.04.2017 07:44:09

Нашел на ларакастс похожий трабл, народ там совсем не думает головой и предлагает делать sleep или добавлять счетчик, который будет использоваться в параметре метода ->delay().
Я не готов к таким костылям, т.к. в первом случае со sleep - может выйти ограничение по времени, если обрабатывать все GetAPIItem в одной задаче, а делать что-то вроде --timout 99999999 я считаю идиотизмом.
А во втором случае с delay опять же возникнет проблема, что задачи могут пересечься и в итоге одна из них "сфейлится".

#30 Re: Laravel 5.x » Отсутствует задержка при выполнении задачи (Job) из очереди (Queue) » 04.04.2017 07:34:39

Перечитал русскую документацию о параметре sleep и удивился, что я не правильно понял его в англоязычной документации.

Почему реализовано так, что перед каждой задачей он не применяется?

Как мне это обойти и запускать задачи из одной очереди с какой-либо задержкой?

Была мысль запускать ежеминутно через schedule команду queue:work, но она почему-то запускает сразу все имеющиеся задачи, а не одну (как написано в документации).

И вопрос из PPS про фейлинг задачи всё ещё не решен...

#31 Re: Laravel 5.x » Отсутствует задержка при выполнении задачи (Job) из очереди (Queue) » 04.04.2017 07:23:39

Версия Laravel: v5.4.16
Версия PHP: 7.1.3
Операционная система и её версия: macOS 10.12.4
Вендор и версия сервера БД: mysql  Ver 14.14 Distrib 5.7.17, for osx10.12
Вендор и версия Веб-сервера: nginx/1.10.3
Медод подключения PHP: Valet

#32 Laravel 5.x » Отсутствует задержка при выполнении задачи (Job) из очереди (Queue) » 04.04.2017 07:12:54

Lord_Alfred
Ответов: 14

Недавно начал изучать Laravel, поставил через Valet последнюю версию.
Пилю систему, которая работает со сторонним API, которое ограничивает количество запросов, поэтому сразу же начал писать используя очередь. Но столкнулся с неприятной особенностью/багом - при запуске:

php artisan queue:work --delay=60 --tries=3 --sleep=5

Все задачи выполняются подряд и без всяких задержек:

[2017-04-04 04:04:43] Processed: App\Jobs\GetAPIData
[2017-04-04 04:04:43] Processed: App\Jobs\GetAPIItem
[2017-04-04 04:04:44] Processed: App\Jobs\GetAPIItem
[2017-04-04 04:04:44] Processed: App\Jobs\GetAPIItem
[2017-04-04 04:04:45] Processed: App\Jobs\GetAPIItem
[2017-04-04 04:04:45] Processed: App\Jobs\GetAPIItem
[2017-04-04 04:04:46] Processed: App\Jobs\GetAPIItem
[2017-04-04 04:04:46] Processed: App\Jobs\GetAPIItem
[2017-04-04 04:04:46] Processed: App\Jobs\GetAPIItem
[2017-04-04 04:04:47] Processed: App\Jobs\GetAPIItem
[2017-04-04 04:04:47] Processed: App\Jobs\GetAPIItem
[2017-04-04 04:04:48] Processed: App\Jobs\GetAPIItem
...

Здесь первая задача GetAPIData получает данные от провайдера и добавляет в очередь ещё кучу задач GetAPIItem. Первую задачу запускаю через schedule, но это вообщем-то не играет особой роли. Она просто попадает в очередь, а потом уже я запускаю команду для запуска очереди.

К слову, использую драйвер database, не sync. Проверял в tinker через env().


Вначале пытался сделать это через задание определенной очереди, запускал с соответствующим аргументом и получал тоже самое.

Пытался прописывать одноименные параметры в классах задач - результат тот же (если, конечно, правильно прописывал).

Я что-то делаю не так или не понимаю логику задержек?

PS: пожалуйста, не советуйте использовать ->delay(время) - это отвратительный метод. У меня несколько задач будет, которые работают с API и там могут возникнуть ситуации, что они пересекутся, а отлавливать эти моменты ой как не просто будет.


PPS: ещё заметил, что если задача зафейлилась, то она не возвращается обратно, хотя установленое количество попыток - 3.

Подвал раздела