Is there a possibility to prevent that certain messages (e.g. those implementing a certain interface) are sent to the failure transport after being rejected (after multiple retries)?
Asked
Active
Viewed 1,004 times
1 Answers
4
Here is one way to do that.
Component that sends failed messages to the failure transport, is registered in the container under the name messenger.failure.send_failed_message_to_failure_transport_listener
.
It's an event listener that handles WorkerMessageFailedEvent
s.
The idea is to decorate it with a simple wrapper that would check if a failed message implements certain interface (or any other possible condition holds true), then handling should be skipped. Otherwise, the original event listener is called.
# config/services.yaml
services:
# ...
App\EventListener\SendFailedMessageToFailureTransportListenerDecorator:
decorates: messenger.failure.send_failed_message_to_failure_transport_listener
<?php
namespace App\EventListener;
use App\Events\SomeEventInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Messenger\Event\WorkerMessageFailedEvent;
use Symfony\Component\Messenger\EventListener\SendFailedMessageToFailureTransportListener;
class SendFailedMessageToFailureTransportListenerDecorator implements EventSubscriberInterface
{
private SendFailedMessageToFailureTransportListener $decoratedListener;
public function __construct(SendFailedMessageToFailureTransportListener $decoratedListener)
{
$this->decoratedListener = $decoratedListener;
}
public static function getSubscribedEvents()
{
return SendFailedMessageToFailureTransportListener::getSubscribedEvents();
}
public function onMessageFailed(WorkerMessageFailedEvent $event)
{
if (!$event->getEnvelope()->getMessage() instanceof SomeEventInterface) {
$this->decoratedListener->onMessageFailed($event);
}
}
}

xtx
- 4,306
- 4
- 28
- 30