Laravel: смена названия broadcast канала и очередь redis

171
11 января 2022, 19:00

Тестировал широковещание Ларавел. Просто по https://laravel.com/docs/6.x/broadcasting только без приватности и проверки доступа.

Установлено: laravel echo, laravel echo server, socket.io-client, predis

Кейс: меняю название канала в классе события. Т.е:

public function broadcastOn()
{
        return new Channel('new_channel_name');
}

Но название канала не меняется, пока я не перезапущу сервис работы очереди. То что не поменялось смотрю по тому, что отдает laravel-echo-server в devmode.

Как это работает? Почему я меняю код, но по факту название Канала меняется только при перезапуске обработчика очереди?

Answer 1

В Laravel каждый Job, включая описанный в документации обработчик broadcast-событий, оформляется в виде отдельного класса-обработчика. Выполнением этих Job'ов фактически занимается отдельный процесс операционной системы, запускаемый консольной командой php artisan queue:work и являющийся зацикленным процессом с простым алгоритмом:

  1. Инициализировать обработчик очереди.
  2. Проверить обрабатываемую (ые) очередь (очереди).
  3. Если есть Job:
    • прочитать его из очереди;
    • если класс Job'а еще не загружен - загрузить его исходник и исходники всех требуемые ему классов с помощью автозагрузчика;
    • создать экземпляр Job'а;
    • выполнить метод handle() в этом экземпляре Job'а;
    • перейти к п.2.
  4. Если очередь пуста:
    • подождать некоторое время (задаваемое параметром --timeout=...);
    • перейти к п.2

Это, конечно, очень упрощенный алгоритм, но он позволяет понять логику работы. Если у Вас какой-либо Job в этом обработчике уже хотя бы один раз выполнился - то класс этого Job'а, а также все требуемые им классы (в Вашем случае - класс события с названием канала), уже загружены автозагрузчиком в том виде, в котором были на момент первого обращения. Соответственно, внося изменения в исходный код этого Job'а или любого им используемого класса (в Вашем случае - класса события, в котором Вы меняете наименование канала), Вы должны перезапустить обработчик. Просто потому, что повторно читать исходный код загруженных классов он не будет - класс уже загружен в том виде, в котором он был на момент первого к нему обращения.

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

Таким образом, для добавления новых Job'ов перезагружать обработчик очереди не нужно. Но вот для того, чтобы заработал измененный код, обработчик придется перезапустить. Иначе никак.

READ ALSO
Как в PHP set_error_handler перехватить все ошибки PDO?

Как в PHP set_error_handler перехватить все ошибки PDO?

Работаю с базой данных MYSQL через интерфейс PDOНужно ошибки баз данных записывать в отдельный log

89
Как делать динамические роуты в PHP?

Как делать динамические роуты в PHP?

Имеется один физический раздел который называется catalog из него читается файл indexphp в котором будет расположена основная логика каталога

132
Сохранение значения при переходе на другую страницу

Сохранение значения при переходе на другую страницу

Как сделать, чтобы значение сохранялось при переходе на другую страницу?

79