From 8a434ad5b3f2e8abdd5516d86f0339cb2a598adc Mon Sep 17 00:00:00 2001 From: Kevin Bond Date: Fri, 7 Jan 2022 18:13:22 -0500 Subject: [PATCH] [feature] add ability to enable retries --- README.md | 20 +++++++++++++++++--- src/Transport/TestTransport.php | 12 +++++++++++- src/Transport/TestTransportFactory.php | 1 + tests/Fixture/config/multi_transport.yaml | 4 +++- tests/InteractsWithMessengerTest.php | 18 +++++++++++++++++- 5 files changed, 49 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 8c91fae..58b5d62 100644 --- a/README.md +++ b/README.md @@ -268,10 +268,10 @@ framework: async: test://?intercept=false ``` -### Testing serialization +### Testing Serialization -By default, the bundle tests if the envelopes could be serialized and deserialized. -This behavior can be disabled at transport level: +By default, the `TestTransport` tests that messages can be serialized and deserialized. +This behavior can be disabled with the transport dsn: ```yaml # config/packages/test/messenger.yaml @@ -282,6 +282,20 @@ framework: async: test://?test_serialization=false ``` +### Enable Retries + +By default, the `TestTransport` does not retry failed messages (your retry settings +are ignored). This behavior can be disabled with the transport dsn: + +```yaml +# config/packages/test/messenger.yaml + +framework: + messenger: + transports: + async: test://?disable_retries=false +``` + ### Multiple Transports If you have multiple transports you'd like to test, change all their dsn's to diff --git a/src/Transport/TestTransport.php b/src/Transport/TestTransport.php index bbbb8e2..d47f30f 100644 --- a/src/Transport/TestTransport.php +++ b/src/Transport/TestTransport.php @@ -25,6 +25,7 @@ final class TestTransport implements TransportInterface 'intercept' => true, 'catch_exceptions' => true, 'test_serialization' => true, + 'disable_retries' => true, ]; private string $name; @@ -41,6 +42,9 @@ final class TestTransport implements TransportInterface /** @var array */ private static array $testSerialization = []; + /** @var array */ + private static array $disableRetries = []; + /** @var array */ private static array $dispatched = []; @@ -68,6 +72,7 @@ public function __construct(string $name, MessageBusInterface $bus, EventDispatc self::$intercept[$name] ??= $options['intercept']; self::$catchExceptions[$name] ??= $options['catch_exceptions']; self::$testSerialization[$name] ??= $options['test_serialization']; + self::$disableRetries[$name] ??= $options['disable_retries']; } /** @@ -229,7 +234,7 @@ public function reject(Envelope $envelope): void public function send(Envelope $envelope): Envelope { - if ($envelope->last(RedeliveryStamp::class)) { + if ($this->isRetriesDisabled() && $envelope->last(RedeliveryStamp::class)) { // message is being retried, don't process return $envelope; } @@ -282,6 +287,11 @@ private function shouldTestSerialization(): bool return self::$testSerialization[$this->name]; } + private function isRetriesDisabled(): bool + { + return self::$disableRetries[$this->name]; + } + private function hasMessagesToProcess(): bool { return !empty(self::$queue[$this->name] ?? []); diff --git a/src/Transport/TestTransportFactory.php b/src/Transport/TestTransportFactory.php index 50b2eec..d44b403 100644 --- a/src/Transport/TestTransportFactory.php +++ b/src/Transport/TestTransportFactory.php @@ -46,6 +46,7 @@ private function parseDsn(string $dsn): array 'intercept' => \filter_var($query['intercept'] ?? true, \FILTER_VALIDATE_BOOLEAN), 'catch_exceptions' => \filter_var($query['catch_exceptions'] ?? true, \FILTER_VALIDATE_BOOLEAN), 'test_serialization' => \filter_var($query['test_serialization'] ?? true, \FILTER_VALIDATE_BOOLEAN), + 'disable_retries' => \filter_var($query['disable_retries'] ?? true, \FILTER_VALIDATE_BOOLEAN), ]; } } diff --git a/tests/Fixture/config/multi_transport.yaml b/tests/Fixture/config/multi_transport.yaml index aa79174..83f446c 100644 --- a/tests/Fixture/config/multi_transport.yaml +++ b/tests/Fixture/config/multi_transport.yaml @@ -9,7 +9,9 @@ framework: async2: dsn: test://?intercept=false&catch_exceptions=false&test_serialization=false async3: in-memory:// + async4: + dsn: test://?disable_retries=false routing: - Zenstruck\Messenger\Test\Tests\Fixture\Messenger\MessageA: [async1] + Zenstruck\Messenger\Test\Tests\Fixture\Messenger\MessageA: [async1, async4] Zenstruck\Messenger\Test\Tests\Fixture\Messenger\MessageB: [async2] Zenstruck\Messenger\Test\Tests\Fixture\Messenger\MessageG: [async2] diff --git a/tests/InteractsWithMessengerTest.php b/tests/InteractsWithMessengerTest.php index 762b0c0..d254a13 100644 --- a/tests/InteractsWithMessengerTest.php +++ b/tests/InteractsWithMessengerTest.php @@ -336,7 +336,7 @@ public function queue_name_is_required_if_using_multiple_transports(): void self::bootKernel(['environment' => 'multi_transport']); $this->expectException(\LogicException::class); - $this->expectExceptionMessage('Multiple transports are registered (async1, async2, async3), you must specify a name.'); + $this->expectExceptionMessage('Multiple transports are registered (async1, async2, async3, async4), you must specify a name.'); $this->messenger(); } @@ -781,6 +781,22 @@ public function serialization_problem_assertions(): void Assert::run(fn() => $this->messenger('async2')->send(new Envelope(new MessageG()))); } + /** + * @test + */ + public function can_enable_retries(): void + { + self::bootKernel(['environment' => 'multi_transport']); + + self::getContainer()->get(MessageBusInterface::class)->dispatch(new MessageA(true)); + + $this->messenger('async4') + ->process() + ->rejected() + ->assertContains(MessageA::class, 4) + ; + } + protected static function bootKernel(array $options = []): KernelInterface { return parent::bootKernel(\array_merge(['environment' => 'single_transport'], $options));