Laravel 5.5 — пользовательские теги Horizon для прослушивателя событий в очереди

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

Когда это делается в очереди событий, это не работает. На самом деле, конструктор, кажется, никогда не вызывается вообще, потому что модель сериализуется и «гидратируется», когда дело доходит до выполнения. Так что подсказка типа в конструкторе ничего не делает, и tags() кажется, вызывается раньше handle(), поэтому я не могу получить доступ к объекту события, который слушаю.

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

Обновить:

Событие вызвано в контроллере:

event(new PostWasCreated($user, $post));

Событие PostWasCreated:

<?php
namespace App\Events;

use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use App\User;
use App\Post;

class PostWasCreated
{
use InteractsWithSockets, SerializesModels;

public $user;
public $post;

public function __construct(User $user, Post $post)
{
$this->user = $user;
$this->post = $post;
}

public function broadcastOn()
{
return new PrivateChannel('channel-name');
}
}

слушатель PostWasCreatedNotificationSend:

<?php
namespace App\Listeners;

use App\Events\PostWasCreated;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;

class PostWasCreatedNotificationSend implements ShouldQueue
{
protected $event;
public $queue = 'notifications'; // Adds queue name

public function __construct(PostWasCreated $event)
{
$this->event = $event;
// Does NOT add queue tag
$this->queueTags = ['post: ' . $this->event->post->id];
}

public function tags()
{
return $this->queueTags;
}

public function handle(PostWasCreated $event)
{
// handle event here...
}
}

Вопрос $this->queueTags никогда не назначается, поэтому в Horizon для этого прослушивателя в очереди нет тегов … (хотя имя очереди отображается, но нам также нужны теги).

2

Решение

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

Для слушателей, находящихся в очереди, система тегов проверяет теги как для объекта события, так и для класса слушателя. Как описано в вопросе, нет способа установить теги с динамическими данными на слушателе, потому что обработчик выполняет после Горизонт вытаскивает работу из очереди. Мы можем только объявить статические теги на слушателе, что Horizon объединит * с тегами на событии:

class PostWasCreatedNotificationSend implements ShouldQueue
{
...
public function tags()
{
return [ 'listener:' . static::class, 'category:posts' ];
}
}

С помощью объекта события Horizon пытается автоматически сгенерировать теги для любых членов модели Eloquent. Например, Horizon создаст следующие теги для PostWasCreated событие:

  • $event->userApp\User:<id>
  • $event->postApp\Post:<id>

Мы можем переопределить это поведение и сообщить Horizon, какие теги установить для события, определив tags() метод как выше:

class PostWasCreated
{
...
public function tags()
{
return [ 'post:' . $this->post->id ];
}
}

Обратите внимание, что во время написания Horizon не будет автоматически создавать теги для моделей, если событие или же слушатель предоставляет теги вручную.

Вопрос $this->queueTags никогда не назначается, поэтому в Horizon для этого прослушивателя в очереди нет тегов … (хотя имя очереди отображается, но нам также нужны теги).

Horizon не создает теги для каждого свойства; автоматическая пометка работает только для тех, которые содержат модели Eloquent (и, как правило, не для слушателя).


* Если событие также используется для трансляции (оно реализует ShouldBroadcast), дополнительное задание, созданное для публикации сообщения, не наследует никаких тегов, предоставленных слушателем.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]