From d231e82313609a1d1470934b99c2b6a395cd3779 Mon Sep 17 00:00:00 2001 From: viktorprogger Date: Sun, 15 Sep 2024 22:01:15 +0500 Subject: [PATCH] Move fromMessage() method out of EnvelopeTrait and create its own key for the FailureEnvelope. --- src/Message/EnvelopeTrait.php | 5 ----- src/Message/IdEnvelope.php | 5 +++++ .../FailureHandling/FailureEnvelope.php | 12 +++++++++++- .../ExponentialDelayMiddleware.php | 16 +++++++--------- .../Implementation/SendAgainMiddleware.php | 18 ++++++++---------- .../ExponentialDelayMiddlewareTest.php | 13 ++++++++++--- .../Implementation/SendAgainMiddlewareTest.php | 4 ++++ 7 files changed, 45 insertions(+), 28 deletions(-) diff --git a/src/Message/EnvelopeTrait.php b/src/Message/EnvelopeTrait.php index 7e58a97b..cc52cf15 100644 --- a/src/Message/EnvelopeTrait.php +++ b/src/Message/EnvelopeTrait.php @@ -31,11 +31,6 @@ public function getData(): mixed return $this->message->getData(); } - public static function fromMessage(MessageInterface $message): self - { - return new static($message); - } - public function getMetadata(): array { return array_merge( diff --git a/src/Message/IdEnvelope.php b/src/Message/IdEnvelope.php index dec2d679..bbf0d67f 100644 --- a/src/Message/IdEnvelope.php +++ b/src/Message/IdEnvelope.php @@ -19,6 +19,11 @@ public function __construct( ) { } + public static function fromMessage(MessageInterface $message): self + { + return new self($message, $message->getMetadata()[self::MESSAGE_ID_KEY] ?? null); + } + public function setId(string|int|null $id): void { $this->id = $id; diff --git a/src/Middleware/FailureHandling/FailureEnvelope.php b/src/Middleware/FailureHandling/FailureEnvelope.php index a8726285..0f6a62e9 100644 --- a/src/Middleware/FailureHandling/FailureEnvelope.php +++ b/src/Middleware/FailureHandling/FailureEnvelope.php @@ -12,14 +12,24 @@ final class FailureEnvelope implements EnvelopeInterface { use EnvelopeTrait; + public const FAILURE_META_KEY = 'failure-meta'; + public function __construct( private MessageInterface $message, private array $meta = [], ) { } + public static function fromMessage(MessageInterface $message): self + { + return new self($message, $message->getMetadata()[self::FAILURE_META_KEY] ?? []); + } + public function getMetadata(): array { - return array_merge($this->message->getMetadata(), $this->meta); + $meta = $this->message->getMetadata(); + $meta[self::FAILURE_META_KEY] = array_merge($meta[self::FAILURE_META_KEY] ?? [], $this->meta); + + return $meta; } } diff --git a/src/Middleware/FailureHandling/Implementation/ExponentialDelayMiddleware.php b/src/Middleware/FailureHandling/Implementation/ExponentialDelayMiddleware.php index 07d0f640..643ab31c 100644 --- a/src/Middleware/FailureHandling/Implementation/ExponentialDelayMiddleware.php +++ b/src/Middleware/FailureHandling/Implementation/ExponentialDelayMiddleware.php @@ -5,7 +5,6 @@ namespace Yiisoft\Queue\Middleware\FailureHandling\Implementation; use InvalidArgumentException; -use Yiisoft\Queue\Message\Message; use Yiisoft\Queue\Message\MessageInterface; use Yiisoft\Queue\Middleware\FailureHandling\FailureHandlingRequest; use Yiisoft\Queue\Middleware\FailureHandling\MessageFailureHandlerInterface; @@ -24,7 +23,7 @@ final class ExponentialDelayMiddleware implements MiddlewareFailureInterface public const META_KEY_DELAY = 'failure-strategy-exponential-delay-delay'; /** - * @param string $id A unique id to differentiate two and more objects of this class + * @param string $id A unique id to differentiate two and more instances of this class * @param int $maxAttempts Maximum attempts count for this strategy with the given $id before it will give up * @param float $delayInitial The first delay period * @param float $delayMaximum The maximum delay period @@ -84,21 +83,20 @@ private function suites(MessageInterface $message): bool private function createNewMeta(MessageInterface $message): array { - $meta = $message->getMetadata(); - $meta[self::META_KEY_DELAY . "-$this->id"] = $this->getDelay($message); - $meta[self::META_KEY_ATTEMPTS . "-$this->id"] = $this->getAttempts($message) + 1; - - return $meta; + return [ + self::META_KEY_DELAY . "-$this->id" => $this->getDelay($message), + self::META_KEY_ATTEMPTS . "-$this->id" => $this->getAttempts($message) + 1, + ]; } private function getAttempts(MessageInterface $message): int { - return $message->getMetadata()[self::META_KEY_ATTEMPTS . "-$this->id"] ?? 0; + return $message->getMetadata()[FailureEnvelope::FAILURE_META_KEY][self::META_KEY_ATTEMPTS . "-$this->id"] ?? 0; } private function getDelay(MessageInterface $message): float { - $meta = $message->getMetadata(); + $meta = $message->getMetadata()[FailureEnvelope::FAILURE_META_KEY] ?? []; $key = self::META_KEY_DELAY . "-$this->id"; $delayOriginal = (float) ($meta[$key] ?? 0); diff --git a/src/Middleware/FailureHandling/Implementation/SendAgainMiddleware.php b/src/Middleware/FailureHandling/Implementation/SendAgainMiddleware.php index 43ac16f4..a7ae792a 100644 --- a/src/Middleware/FailureHandling/Implementation/SendAgainMiddleware.php +++ b/src/Middleware/FailureHandling/Implementation/SendAgainMiddleware.php @@ -20,14 +20,15 @@ final class SendAgainMiddleware implements MiddlewareFailureInterface public const META_KEY_RESEND = 'failure-strategy-resend-attempts'; /** - * @param string $id A unique id to differentiate two and more objects of this class + * @param string $id A unique id to differentiate two and more instances of this class * @param int $maxAttempts Maximum attempts count for this strategy with the given $id before it will give up - * @param QueueInterface|null $queue + * @param QueueInterface|null $targetQueue Messages will be sent to this queue if set. + * They will be resent to an original queue otherwise. */ public function __construct( private string $id, private int $maxAttempts, - private ?QueueInterface $queue = null, + private ?QueueInterface $targetQueue = null, ) { if ($maxAttempts < 1) { throw new InvalidArgumentException("maxAttempts parameter must be a positive integer, $this->maxAttempts given."); @@ -41,10 +42,10 @@ public function processFailure( $message = $request->getMessage(); if ($this->suites($message)) { $envelope = new FailureEnvelope($message, $this->createMeta($message)); - $envelope = ($this->queue ?? $request->getQueue())->push($envelope); + $envelope = ($this->targetQueue ?? $request->getQueue())->push($envelope); return $request->withMessage($envelope) - ->withQueue($this->queue ?? $request->getQueue()); + ->withQueue($this->targetQueue ?? $request->getQueue()); } return $handler->handleFailure($request); @@ -57,15 +58,12 @@ private function suites(MessageInterface $message): bool private function createMeta(MessageInterface $message): array { - $metadata = $message->getMetadata(); - $metadata[$this->getMetaKey()] = $this->getAttempts($message) + 1; - - return $metadata; + return [$this->getMetaKey() => $this->getAttempts($message) + 1]; } private function getAttempts(MessageInterface $message): int { - $result = $message->getMetadata()[$this->getMetaKey()] ?? 0; + $result = $message->getMetadata()[FailureEnvelope::FAILURE_META_KEY][$this->getMetaKey()] ?? 0; if ($result < 0) { $result = 0; } diff --git a/tests/Unit/Middleware/FailureHandling/Implementation/ExponentialDelayMiddlewareTest.php b/tests/Unit/Middleware/FailureHandling/Implementation/ExponentialDelayMiddlewareTest.php index 5d24f46a..707a1ad7 100644 --- a/tests/Unit/Middleware/FailureHandling/Implementation/ExponentialDelayMiddlewareTest.php +++ b/tests/Unit/Middleware/FailureHandling/Implementation/ExponentialDelayMiddlewareTest.php @@ -8,6 +8,7 @@ use InvalidArgumentException; use PHPUnit\Framework\Attributes\DataProvider; use Yiisoft\Queue\Message\Message; +use Yiisoft\Queue\Middleware\FailureHandling\FailureEnvelope; use Yiisoft\Queue\Middleware\FailureHandling\FailureHandlingRequest; use Yiisoft\Queue\Middleware\FailureHandling\Implementation\ExponentialDelayMiddleware; use Yiisoft\Queue\Middleware\FailureHandling\MessageFailureHandlerInterface; @@ -148,8 +149,11 @@ public function testPipelineSuccess(): void self::assertNotEquals($request, $result); $message = $result->getMessage(); - self::assertArrayHasKey(ExponentialDelayMiddleware::META_KEY_ATTEMPTS . '-test', $message->getMetadata()); - self::assertArrayHasKey(ExponentialDelayMiddleware::META_KEY_DELAY . '-test', $message->getMetadata()); + self::assertArrayHasKey(FailureEnvelope::FAILURE_META_KEY, $message->getMetadata()); + + $meta = $message->getMetadata()[FailureEnvelope::FAILURE_META_KEY]; + self::assertArrayHasKey(ExponentialDelayMiddleware::META_KEY_ATTEMPTS . '-test', $meta); + self::assertArrayHasKey(ExponentialDelayMiddleware::META_KEY_DELAY . '-test', $meta); } public function testPipelineFailure(): void @@ -157,7 +161,10 @@ public function testPipelineFailure(): void $this->expectException(Exception::class); $this->expectExceptionMessage('test'); - $message = new Message('test', null, [ExponentialDelayMiddleware::META_KEY_ATTEMPTS . '-test' => 2]); + $message = new Message( + 'test', + null, + [FailureEnvelope::FAILURE_META_KEY => [ExponentialDelayMiddleware::META_KEY_ATTEMPTS . '-test' => 2]]); $queue = $this->createMock(QueueInterface::class); $middleware = new ExponentialDelayMiddleware( 'test', diff --git a/tests/Unit/Middleware/FailureHandling/Implementation/SendAgainMiddlewareTest.php b/tests/Unit/Middleware/FailureHandling/Implementation/SendAgainMiddlewareTest.php index 57dc4eb9..665c6bea 100644 --- a/tests/Unit/Middleware/FailureHandling/Implementation/SendAgainMiddlewareTest.php +++ b/tests/Unit/Middleware/FailureHandling/Implementation/SendAgainMiddlewareTest.php @@ -10,6 +10,7 @@ use RuntimeException; use Yiisoft\Queue\Message\Message; use Yiisoft\Queue\Message\MessageInterface; +use Yiisoft\Queue\Middleware\FailureHandling\FailureEnvelope; use Yiisoft\Queue\Middleware\FailureHandling\FailureHandlingRequest; use Yiisoft\Queue\Middleware\FailureHandling\Implementation\ExponentialDelayMiddleware; use Yiisoft\Queue\Middleware\FailureHandling\Implementation\SendAgainMiddleware; @@ -150,6 +151,9 @@ public function testQueueSendingStrategies( $this->expectExceptionMessage('testException'); } + $metaInitial = [FailureEnvelope::FAILURE_META_KEY => $metaInitial]; + $metaResult = [FailureEnvelope::FAILURE_META_KEY => $metaResult]; + $handler = $this->getHandler($metaResult, $suites); $queue = $this->getPreparedQueue($metaResult, $suites);