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)?
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)?
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 WorkerMessageFailedEvents.
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);
}
}
}