Skip to content

[Messenger] fromTransport in attribute not working #48529

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
bzajacc opened this issue Dec 7, 2022 · 3 comments
Closed

[Messenger] fromTransport in attribute not working #48529

bzajacc opened this issue Dec 7, 2022 · 3 comments

Comments

@bzajacc
Copy link

bzajacc commented Dec 7, 2022

Symfony version(s) affected

5.4

Description

Handler attribute with fromTransport option not working

#[AsMessageHandler(fromTransport: self::QUEUE_NAME)]

and every handler is executed.

After adding the method with configuration, it works as intended:

public static function getHandledMessages(): iterable
{
    yield Foo::class => [
        'from_transport' => self::QUEUE_NAME,
    ];
}

How to reproduce

<?php
// messsenger.php

namespace Symfony\Component\DependencyInjection\Loader\Configurator;

return static function (ContainerConfigurator $configurator) {
    $configurator->extension('framework', [ 'messenger' => [
        'serializer' => ['default_serializer' => 'messenger.transport.symfony_serializer'],
        'default_bus' => 'messenger.bus.default',
        'bus' => [
            'name' => 'messenger.bus.default'
        ],
        'transports' => [
            FooMessageHandler::QUEUE_NAME => [
                'dsn' => env('AMQP_TRANSPORT_DSN'),
                'options' => [
                    'confirm_timeout' => 0.5,
                    'exchange' => [
                        'name' => FooMessageHandler::QUEUE_NAME,
                        'type' => 'direct',
                    ],
                    'queues' => [
                        FooMessageHandler::QUEUE_NAME => [
                            'arguments' => [
                                'x-dead-letter-exchange' => 'X',
                            ],
                        ],
                    ],
                ],
            ],
            BarMessageHandler::QUEUE_NAME => [
                'dsn' => env('AMQP_TRANSPORT_DSN'),
                'options' => [
                    'exchange' => [
                        'name' => BarMessageHandler::QUEUE_NAME,
                        'type' => 'direct',
                    ],
                    'queues' => [
                        BarMessageHandler::QUEUE_NAME => [
                            'arguments' => [
                                'x-dead-letter-exchange' => 'Y',
                            ],
                        ],
                    ],
                ],
            ],
        ],
        'routing' => [
            IntegrationRequestMessage::class => [
                FooMessageHandler::QUEUE_NAME,
                BarMessageHandler::QUEUE_NAME,
            ],
        ],
    ]]);
};

Handlers:

#[AsMessageHandler(fromTransport: self::QUEUE_NAME)]
final class FooMessageHandler implements MessageHandlerInterface
{
    public const QUEUE_NAME = 'foo';

    public function __invoke(IntegrationRequestMessage $message): void
    {
        echo 'Foo';
    }
}
#[AsMessageHandler(fromTransport: self::QUEUE_NAME)]
final class BarMessageHandler implements MessageHandlerInterface
{
    public const QUEUE_NAME = 'bar';

    public function __invoke(IntegrationRequestMessage $message): void
    {
        echo 'Bar';
    }
}

Possible Solution

No response

Additional Context

No response

@xabbuh
Copy link
Member

xabbuh commented Dec 7, 2022

Can you create a small example application that allows to reproduce your issue?

@xabbuh
Copy link
Member

xabbuh commented Dec 17, 2022

I am going to close here for now due to the lack of feedback. Please let us know when you have more information and we can consider to reopen.

@xabbuh xabbuh closed this as not planned Won't fix, can't repro, duplicate, stale Dec 17, 2022
@valtzu
Copy link
Contributor

valtzu commented Nov 22, 2023

I think this is still an issue on 6.3 – from_transportworks only on normal methods, not on __invoke – and this would be resolved by https://github.com/symfony/symfony/pull/52693/files#diff-75de6432729b1204125a041fe528c9b844fd769e01ba4e2ea649ffcc57b16e85R135 though it's not the main thing it addresses.

nicolas-grekas added a commit that referenced this issue Nov 24, 2023
…ports` (valtzu)

This PR was merged into the 6.3 branch.

Discussion
----------

[Messenger] Fix message handlers with multiple `from_transports`

| Q             | A
| ------------- | ---
| Branch?       | 6.3
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Issues | Fix #48529
| License       | MIT

When you define multiple `AsMessageHandler` attributes or `messenger.message_handler` tags with otherwise same definitions but with different transports, the last definition overwrites all previous ones, despite `debug:messenger` showing it correctly:

```
 The following messages can be dispatched:

 --------------------------------------------------------------------------------------------------------------------
  App\Message\TriggeringMessage
      handled by App\MessageHandler\TriggeringMessageHandler (when from_transport=a)
      handled by App\MessageHandler\TriggeringMessageHandler (when from_transport=b)
      handled by App\MessageHandler\TriggeringMessageHandler (when method=handleTriggeringMessage, from_transport=a)
      handled by App\MessageHandler\TriggeringMessageHandler (when method=handleTriggeringMessage, from_transport=b)
```

Example code:

```php
#[AsMessageHandler(fromTransport: 'a', handles: TriggeringMessage::class)]
#[AsMessageHandler(fromTransport: 'b', handles: TriggeringMessage::class)]
class TriggeringMessageHandler
{
    public function __invoke(): void
    {
        echo __FUNCTION__."\n";
    }

    #[AsMessageHandler(fromTransport: 'a', handles: TriggeringMessage::class)]
    #[AsMessageHandler(fromTransport: 'b', handles: TriggeringMessage::class)]
    public function handleTriggeringMessage(): void
    {
        echo __FUNCTION__."\n";
    }
}
```

When sending a `TriggeringMessage` to both `a` & `b` transports, I get following `bin/console messenger:consume a b` output on **6.3**:

```
[critical] Error thrown while handling message App\Message\TriggeringMessage. Removing from transport after 0 retries. Error: "No handler for message "App\Message\TriggeringMessage"."
__invoke
handleTriggeringMessage
```

And with this fix:
```
__invoke
handleTriggeringMessage
__invoke
handleTriggeringMessage
```

Commits
-------

bff3cc1 Fix message handlers with multiple from_transports
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants