<?php declare(strict_types=1);
namespace Shopware\Core\Framework\MessageQueue\Subscriber;
use Shopware\Core\Framework\Increment\Exception\IncrementGatewayNotFoundException;
use Shopware\Core\Framework\Increment\IncrementGatewayRegistry;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Messenger\Envelope;
use Symfony\Component\Messenger\Event\WorkerMessageFailedEvent;
use Symfony\Component\Messenger\Stamp\ReceivedStamp;
class MessageFailedHandler implements EventSubscriberInterface
{
private string $defaultTransportName;
private IncrementGatewayRegistry $gatewayRegistry;
/**
* @internal
*/
public function __construct(IncrementGatewayRegistry $gatewayRegistry, string $defaultTransportName)
{
$this->defaultTransportName = $defaultTransportName;
$this->gatewayRegistry = $gatewayRegistry;
}
public static function getSubscribedEvents(): array
{
return [
// must have higher priority than SendFailedMessageToFailureTransportListener
WorkerMessageFailedEvent::class => ['onMessageFailed', 99],
];
}
public function onMessageFailed(WorkerMessageFailedEvent $event): void
{
if ($event->willRetry()) {
return;
}
$message = $event->getEnvelope();
if (!$this->wasReceivedByDefaultTransport($message)) {
return;
}
$name = \get_class($message->getMessage());
try {
$gateway = $this->gatewayRegistry->get(IncrementGatewayRegistry::MESSAGE_QUEUE_POOL);
} catch (IncrementGatewayNotFoundException $exception) {
return;
}
$gateway->decrement('message_queue_stats', $name);
}
private function wasReceivedByDefaultTransport(Envelope $message): bool
{
foreach ($message->all(ReceivedStamp::class) as $stamp) {
if ($stamp instanceof ReceivedStamp && $stamp->getTransportName() === $this->defaultTransportName) {
return true;
}
}
return false;
}
}