How to prevent message to be sent to the failure transport?

1.2k Views Asked by At

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)?

1

There are 1 best solutions below

0
On

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);
        }
    }
}