Description
Symfony version(s) affected
7.0+
Description
I've faced a scenario, when I want my batch handler to be handling messages only from specific transport, and for that I'm adding corresponding AsMessageHandler
attribute with fromTransport
option, but when I do so, MessengerPass registers two separate HandlerDescriptors inside the HandlersLocator, as it now has two messenger.message_handler
tags (one with from_transport opiton, another - without)
As the result, MyBatchHandler starts consuming MyMessage from any transport, which is not I expected.
How to reproduce
- Install
symfony/messenger
component - Create the following handler and message
<?php
namespace App;
use Symfony\Component\Messenger\Attribute\AsMessageHandler;
use Symfony\Component\Messenger\Handler\Acknowledger;
use Symfony\Component\Messenger\Handler\BatchHandlerInterface;
#[AsMessageHandler(fromTransport: 'custom')]
class MyBatchHandler implements BatchHandlerInterface
{
public function __invoke(MyMessage $message, ?Acknowledger $ack = null): null
{
// dummy
return null;
}
public function flush(bool $force): void
{
// dummy
}
}
class MyMessage {
}
- Run
bin/console debug:container MyBatchHandler
and see twomessenger.message_handler
tags (one expected) - Run
bin/console debug:messenger
and see there are two handlers for MyMessage class (one expected)
Possible Solution
I'd suggest removing change introduced in PR #44490 and let people add #[AsMessageHandler]
attribute manually as recommended for regular handlers - this would be more intuitive for developers IMO
As this is a BC break, it's probably best to introduce this change in symfony/messenger v8.0
As a workaround, it's possible to opt-out from auto-registration for this particular handler and declare handler tag manually:
#config/services.php
<?php
declare(strict_types=1);
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $container, string $env): void {
$services = $container->services();
$services->defaults()
->autowire()
->autoconfigure();
// other autoconfigured services
$services
->set(\App\MyBatchHandler::class)
->autoconfigure(autoconfigured: false)
->tag('messenger.message_handler', [
'from_transport' => 'custom',
]);
};