8000 [Messenger] Add a way to only call the handler assigned to a queue · Issue #30110 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

[Messenger] Add a way to only call the handler assigned to a queue #30110

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
tkocjan opened this issue Feb 7, 2019 · 3 comments
Closed

[Messenger] Add a way to only call the handler assigned to a queue #30110

tkocjan opened this issue Feb 7, 2019 · 3 comments

Comments

@tkocjan
Copy link
tkocjan commented Feb 7, 2019

Description
With RabbitMQ you can set up a topic in a pub/sub configuration by binding multiple queues to one exchange. You can configure messenger transports to those different queues. The message is sent to the exchange and the same message is posted to both queues. A worker on one queue performs one type of operation (like sending an email) and another worker on the other queue performs a different operation (like sending an SMS).

Here is the problem:

You can set up workers to each of the queues through the transport with “bin/console messenger:consume-messages [transport]”, that works great. The problem is that both workers call both handlers because the message class in both handlers is the same. What is needed is a way to specify the handlers for each worker.

@Tobion
Copy link
Contributor
Tobion commented Feb 8, 2019

It should be possible to implement this with a custom Envelope stamp and a custom https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Messenger/Handler/HandlersLocatorInterface.php so that it only calls the handler that fits with the stamp

@Tobion
Copy link
Contributor
8000 Tobion commented Feb 8, 2019

See discussion in #29045

sroze added a commit that referenced this issue Apr 28, 2019
…transport (sroze)

This PR was merged into the 4.3-dev branch.

Discussion
----------

[Messenger] Allows to register handlers on a specific transport

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #30110
| License       | MIT
| Doc PR        | symfony/symfony-docs#11236

With the #30008 pull-request in, we can now do the following:
```yaml
framework:
    messenger:
        transports:
            events:
                dsn: amqp://guest:guest@127.0.0.1/%2f/events
                options:
                    queues:
                        3rdparty:
                            binding_keys: [ 3rdparty ]
                        projection:
                            binding_keys: [ projection ]

            events_3rdparty: amqp://guest:guest@127.0.0.1/%2f/events?queues[3rdparty]
            events_projection: amqp://guest:guest@127.0.0.1/%2f/events?queues[projection]

        routing:
            'App\Message\RegisterBet': events
```

This will bind two queues to the `events` exchange, fantastic:
<img width="325" alt="Screenshot 2019-04-07 at 10 26 27" src="https://user-images.githubusercontent.com/804625/55680861-af373580-591f-11e9-8f1e-2d3b6ddba2fd.png">

---

Now, in this setup, the message will be duplicated within the `3rdparty` & `projection` queues. If you just run the consumer for each transport, it will consume the message and call all the handlers. You can't do different things based on which queue you have consumed the message. **This pull-request adds the following feature:**

```php
class RegisterBetHandler implements MessageSubscriberInterface
{
    public function __invoke(RegisterBet $message)
    {
        // Do something only when the message comes from the `events_projection` transport...
    }

    /**
     * {@inheritdoc}
     */
    public static function getHandledMessages(): iterable
    {
        yield RegisterBet::class => [
            'from_transport' => 'events_projection',
        ];
    }
}
```

---

In the debugger, it looks like this:
<img width="649" alt="Screenshot 2019-04-07 at 10 29 55" src="https://user-images.githubusercontent.com/804625/55680892-1d7bf800-5920-11e9-80f7-853f0201c6d8.png">

Commits
-------

f0b2acd Allows to register handlers on a specific transport (and get rid of this handler alias)
@chalasr
Copy link
Member
chalasr commented May 26, 2019

Should be resolved by #30958.

@chalasr chalasr closed this as completed May 26, 2019
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
0