From aba6fc2bb2d6cfec6764da3c705e54f671d80f4c Mon Sep 17 00:00:00 2001 From: Frederik Rommel Date: Sat, 16 Mar 2024 01:34:43 +0100 Subject: [PATCH] PAYOSWXP-121: notification-forward: retry on failure (3 retries) --- src/DependencyInjection/webhooks.xml | 2 +- .../Command/NotificationForwardMessage.php | 13 +++++++++++- .../NotificationForwardHandler.php | 21 ++++++++++++++++++- 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/DependencyInjection/webhooks.xml b/src/DependencyInjection/webhooks.xml index 52a36211..b2bdba05 100644 --- a/src/DependencyInjection/webhooks.xml +++ b/src/DependencyInjection/webhooks.xml @@ -35,7 +35,7 @@ - + diff --git a/src/Payone/Webhook/MessageBus/Command/NotificationForwardMessage.php b/src/Payone/Webhook/MessageBus/Command/NotificationForwardMessage.php index b6d4f468..65571bae 100644 --- a/src/Payone/Webhook/MessageBus/Command/NotificationForwardMessage.php +++ b/src/Payone/Webhook/MessageBus/Command/NotificationForwardMessage.php @@ -12,7 +12,8 @@ public function __construct( private readonly string $notificationTargetId, private readonly array $requestData, private readonly string $paymentTransactionId, - private readonly string $clientIp + private readonly string $clientIp, + private int $attempt = 1 ) { } @@ -35,4 +36,14 @@ public function getClientIp(): string { return $this->clientIp; } + + public function getAttempt(): int + { + return $this->attempt; + } + + public function setAttempt(int $attempt): void + { + $this->attempt = $attempt; + } } diff --git a/src/Payone/Webhook/MessageBus/MessageHandler/NotificationForwardHandler.php b/src/Payone/Webhook/MessageBus/MessageHandler/NotificationForwardHandler.php index 1cd050e1..440f561a 100644 --- a/src/Payone/Webhook/MessageBus/MessageHandler/NotificationForwardHandler.php +++ b/src/Payone/Webhook/MessageBus/MessageHandler/NotificationForwardHandler.php @@ -13,14 +13,20 @@ use Shopware\Core\Framework\Uuid\Uuid; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Messenger\Attribute\AsMessageHandler; +use Symfony\Component\Messenger\Envelope; +use Symfony\Component\Messenger\MessageBusInterface; +use Symfony\Component\Messenger\Stamp\DelayStamp; #[AsMessageHandler(handles: NotificationForwardMessage::class)] class NotificationForwardHandler { + private const ATTEMPT_WAIT_TIME_MAPPING = [2 => 5, 3 => 30, 4 => 120]; // maybe we will make this configurable in the future + public function __construct( private readonly EntityRepository $forwardTargetRepository, private readonly EntityRepository $notificationForwardRepository, private readonly LoggerInterface $logger, + private readonly MessageBusInterface $messageBus ) { } @@ -45,10 +51,23 @@ public function __invoke(NotificationForwardMessage $message): void $responseContent = (string)curl_exec($ch); $responseInfo = curl_getinfo($ch); + $statusCode = curl_getinfo($ch, \CURLINFO_RESPONSE_CODE); curl_close($ch); $this->statusLogger($responseInfo, $responseContent, $message); - $this->saveNotificationForward($responseInfo, $responseContent, $message); + $this->saveNotificationForward($responseContent, $message); + + if ($statusCode < 200 || $statusCode >= 300) { + $newMessage = clone $message; + $newMessage->setAttempt($message->getAttempt() + 1); + $waitForNextAttempt = self::ATTEMPT_WAIT_TIME_MAPPING[$newMessage->getAttempt()] ?? null; + if ($waitForNextAttempt === null) { + return; // too many errors - we will not try it again. + } + + $newMessage = new Envelope($newMessage, [new DelayStamp($waitForNextAttempt * 1000 * 60)]); + $this->messageBus->dispatch($newMessage); + } } public static function getHandledMessages(): iterable