Есть ли способ подавить задание в очереди заданий, связанных с отключением вещательного события, когда канал пуст? В основном то, что я замечаю, заключается в том, что, хотя никакие сокеты не будут отключены, если broadcastOn
вернет []
, он все равно сделает задание в очереди. Есть ли способ, чтобы задание в очереди создавалось только тогда, когда broadcastOn
возвращает массив с хотя бы одним элементом?Не пожаловаться в очередь на работу без каналов?
ответ
В Laravel 5.4 теперь вы можете добавить новый метод для событий, broadcastWhen
. Все, что нужно сделать:
public function broadcastOn() {
return [];
}
public function broadcastWith() {
return count($this->broadcastOn()) > 0;
}
Вы можете прочитать больше о том, как broadcastWhen
обрабатывается в source code.
Проверьте, должно ли событие транслироваться по условию.
Чтобы выполнить эту работу, вам нужно будет сделать небольшое подклассическое руководство. Задача в очереди создается в методе broadcastEvent
Illuminate\Events\Dispatcher
.
protected function broadcastEvent($event)
{
if ($this->queueResolver) {
$connection = $event instanceof ShouldBroadcastNow ? 'sync' : null;
$queue = method_exists($event, 'onQueue') ? $event->onQueue() : null;
$this->resolveQueue()->connection($connection)->pushOn($queue, 'Illuminate\Broadcasting\BroadcastEvent', [
'event' => serialize(clone $event),
]);
}
}
Вы можете добавить здесь галочку, чтобы только подтолкнет работу на очереди, если $event->broadcastOn
возвращает массив с, по меньшей мере, один элемент.
После подкласса вам нужно будет использовать новый диспетчер для запуска событий. Вы можете создать для этого нового поставщика услуг и связать его с контейнером. Я не уверен, что вы можете перезаписать существующий экземпляр events
, созданный в Illuminate\Events\EventServiceProvider
, но вы можете определенно создать новый.
public function register()
{
$this->app->singleton('events-custom', function ($app) {
return (new App\Provides\CustomDispatcher($app))->setQueueResolver(function() use ($app) {
return $app->make('Illuminate\Contracts\Queue\Factory');
});
});
}
Если вы используете событие фасад, не забудьте также обновить конфигурационный файл, чтобы указать на новый фасад, который возвращает ключ к вашему новому CustomDispatcher. К сожалению, вспомогательная функция events()
все равно вернет первоначальный диспетчер. Я не верю, что это можно перезаписать. Если вы можете каким-то образом перезаписать существующий ключ events
, установленный Illuminate\Events\EventServiceProvider
, тогда вы все настроены.