Как стать автором
Обновить

Комментарии 12

Если задача уйти от фреймворка, то для простого многопоточного парсера стандартных библиотек php разве недостаточно?


Использование лишних и слабо документированных вещей — так себе решение. Уж лучше фреймворк тогда, я считаю )

Ну нет, от фреймворка уйти нет задачи, а иногда есть задача искать компоненты, не привязанные к определенным фреймворкам. В моём проекте в качестве «фреймворка» используется, грубо говоря, контейнер и request-router, а остальное — компоненты.
Здесь смотрели? У симфони документация по компонентам и по их использованию в рамках фреймворка располагается отдельно.
В конечном итоге, конечно, да, и на этой странице хорошее пояснение с примером на PHP, но на странице о транспорте из Learn more есть примеры только на yml или контейнере симфони.
На самом деле, гораздо лучше будет полностью сконгфигурировать компонент symfony/messenger в контейнере и инжектить интерфейс MessageBusInterface в контроллер.

Кстати, в самом компоненте symfony/messenger уже реализованы несколько полезных команд, включая запуск воркеров. Так что, вместо того, что бы писать свой запуск воркера можно подключить компонент symfony/console и использовать уже имеющийся в компоненте функционал.
Надо будет посмотреть — как раз этот symfony/console затянулся с зависимостями. Хотя я искал использование интерфейсов MessageBus (и прочих) в vendor и не помню, чтоб встретил что-то подходящее.
Я с symfony/messenger так и не разобрался, по моему он излишне усложнён. Хотя в моём случае все решилось гораздо проще и вообще без использования сторонних компонентов.

В приложении добавляем сообщения в очередь методом rPush:
/*
    Code logic
*/

$redis = new Redis();
$redis->rPush("message_queue", "message 1");

А в воркере-обработчике делаем вот так:
$redis = new Redis();
$redis->setOption(Redis::OPT_READ_TIMEOUT, -1);

while(true) {
    list($queue, $message) = $redis->blPop(["message_queue"], 0);
    /*
        Logic to processing $message
    */
}

while тут не выполняется бесконечно, а приостанавливается на blPop в ожидании сообщения.
Если такой подход решает задачу — то вполне норм. Но messenger дает гибкость, ценой создания непонятных абстракций. В принципе, как я и писал выше — я сделал демо по работе с мессенджером с redis streams, состоящий из всего нескольких файлов без всякой лишней мишуры и зависимостей: github.com/backend-university/products/tree/master/products/02-redis-streams-bus.
Может быть будет полезно.
Прекрасный у Вас пример получился. Единственное, перечень используемых в системе сообщений «размазан» по нескольким слоям: упоминания встречаются как непосредственно в примерах (в consumer`ах), так и в конфигурации сервисов (config/container.php).

Вот если бы добавить функцию авторегистрации всех доступных сообщений в контейнер…
Да, там надо роутинг продумать, есть проблемы с «наивным» подходом, например, если поставить "*" в качестве ключа, то тогда нужно будет настраивать group/consumer в коннектах к стримам, иначе консьюмеры будет получать чужие сообщения и делать «nack», удаляя их из стрима (это уже часть реализации messenger).
Думал упомянуть этот в статье, но показалось, что она и так уже растянулась.
Как собрать из кучи классов с универсальными, ни о чём не говорящими названиями, шину для передачи сообщений, да еще и на Redis?

Сконфигурировать в самом симфони на yaml и посмотреть, что в итоге в скомпилированном контейнере уже в php-варианте :)

Не подумал даже, тоже вариант
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Изменить настройки темы

Истории