From 88c832e89b6e82830657f145195dfeb457502d02 Mon Sep 17 00:00:00 2001 From: Ruud Kamphuis Date: Fri, 14 Jul 2023 15:58:13 +0200 Subject: [PATCH] Make `HandleMessageMiddleware::callHandler` protected I made the following changes: - make `callHandler` protected - pass the HandlerDescriptor (can be used to read options from the handler) - pass the Envelope (can be used to read more stamps) This allows people to decorate the `HandleMessageMiddleware` and intercept the moment the handler is called. I currently have the following use cases for this in my application: 1) Every handler can decide if they want to wrap their handling in a transaction. This is done by a custom `#[WrapInTransaction]` attribute. When the attribute is there, we wrap it in a database transaction. I know the `DoctrineTransactionMiddleware` exists in the Symfony Doctrine bridge, but that runs as middleware and cannot be toggled individually. It would be possible to modify it so that it only runs when the handler has it enabled using an option, but that only works for buses with only 1 handler. For an event bus, with multiple handlers, that won't be a solution. 2) Every handler can decide if they want to ignore certain exceptions that are thrown. This is done by a custom `#[IgnoreException]` attribute. For example the handler uses `#[IgnoreException(EventNotFoundException::class)]`. Whenever that exception is thrown, the exception is caught and ignored. The middleware thinks it's executed without issues. --- src/Symfony/Component/Messenger/CHANGELOG.md | 5 +++++ .../Middleware/HandleMessageMiddleware.php | 15 ++++++++------- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/Symfony/Component/Messenger/CHANGELOG.md b/src/Symfony/Component/Messenger/CHANGELOG.md index aabf140f6ce73..b181c707ea2bc 100644 --- a/src/Symfony/Component/Messenger/CHANGELOG.md +++ b/src/Symfony/Component/Messenger/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +6.4 +--- + + * Make `HandleMessageMiddleware::callHandler` protected + 6.3 --- diff --git a/src/Symfony/Component/Messenger/Middleware/HandleMessageMiddleware.php b/src/Symfony/Component/Messenger/Middleware/HandleMessageMiddleware.php index 6b84bd8cfd3ef..1eb20afaa23f2 100644 --- a/src/Symfony/Component/Messenger/Middleware/HandleMessageMiddleware.php +++ b/src/Symfony/Component/Messenger/Middleware/HandleMessageMiddleware.php @@ -79,7 +79,7 @@ public function handle(Envelope $envelope, StackInterface $stack): Envelope $ackStamp->ack($envelope, $e); }); - $result = $this->callHandler($handler, $message, $ack, $envelope->last(HandlerArgumentsStamp::class)); + $result = $this->callHandler($handlerDescriptor, $envelope, $ack); if (!\is_int($result) || 0 > $result) { throw new LogicException(sprintf('A handler implementing BatchHandlerInterface must return the size of the current batch as a positive integer, "%s" returned from "%s".', \is_int($result) ? $result : get_debug_type($result), get_debug_type($batchHandler))); @@ -93,7 +93,7 @@ public function handle(Envelope $envelope, StackInterface $stack): Envelope $result = $ack->getResult(); } } else { - $result = $this->callHandler($handler, $message, null, $envelope->last(HandlerArgumentsStamp::class)); + $result = $this->callHandler($handlerDescriptor, $envelope, null); } $handledStamp = HandledStamp::fromDescriptor($handlerDescriptor, $result); @@ -144,16 +144,17 @@ private function messageHasAlreadyBeenHandled(Envelope $envelope, HandlerDescrip return false; } - private function callHandler(callable $handler, object $message, ?Acknowledger $ack, ?HandlerArgumentsStamp $handlerArgumentsStamp): mixed + protected function callHandler(HandlerDescriptor $handlerDescriptor, Envelope $envelope, ?Acknowledger $ack): mixed { + $handler = $handlerDescriptor->getHandler(); + $message = $envelope->getMessage(); + $additionalArguments = $envelope->last(HandlerArgumentsStamp::class)?->getAdditionalArguments() ?? []; + $arguments = [$message]; if (null !== $ack) { $arguments[] = $ack; } - if (null !== $handlerArgumentsStamp) { - $arguments = [...$arguments, ...$handlerArgumentsStamp->getAdditionalArguments()]; - } - return $handler(...$arguments); + return $handler(...$arguments, ...$additionalArguments); } }