Skip to content

[Messenger] support for multiple bindings on the same queue #38485

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

Open
wants to merge 10 commits into
base: 7.4
Choose a base branch
from

Conversation

inferont
Copy link

@inferont inferont commented Oct 8, 2020

Q A
Branch? master
Bug fix? no
New feature? yes
Tickets Fix #37233
License MIT

Previous Discussion
#37722

Description
When using header based queues and exchanges to keep track of events, one may want to have multiple bindings on those headers in those queues. Adding a few lines of code to Connection.php in amqp-messenger will allow Symfony Messenger to support this type of queue. This is pretty standard in other amqp library implementations.

Details
This PR introduces a small refactoring that deprecates the binding_keys and binding_arguments options with a new array option, bindings. This bindings options allows any number of arrays with a 'key' string value, another 'arguments' array value, and possibly an 'exchange' value in future revisions to support multiple exchanges.

Example

async_consume_task:
    dsn: '%env(MESSENGER_TRANSPORT_DSN)%'
    options:
        vhost: message-bus
        exchange:
            name: message-bus-exchange
            type: headers
        queues:
            'cart-purchases-header-queue':
                'bindings':
                    'manual-messages':
                        'arguments':
                            message-type: 'task'
                            subject: 'cart'
                            x-bind: all
                    'customer-messages':
                        'arguments':
                            message-type: 'event'
                            subject: 'customer'
                            x-bind: all
            'general-events-topic-queue':
                'bindings':
                    0:
                        'key': 'entity-change.*.*.*'

@inferont inferont requested a review from sroze as a code owner October 8, 2020 16:01
@inferont inferont changed the title [Messenger] support for multiple bindings on the same queue #37722 [Messenger] support for multiple bindings on the same queue Oct 8, 2020
@Nyholm
Copy link
Member

Nyholm commented Oct 8, 2020

Thank you for this PR.

It seams like this is a feature specific to AMQP. It is also not a "80% or more people are doing this". I suggest that this advanced/uncommon configuration of AMQP should be done outside the scope of the messenger component.

Correct me if Im wrong, but one could easily configure like RabbitMq to have these bindings and then just use the exchange normally with the messenger component, right?

@inferont
Copy link
Author

inferont commented Oct 8, 2020

@Nyholm
Please also see the discussion in the previous PR at #37233

Having more than one binding is a very common configuration for queues in AMQP. Setting multiple bindings is also supported by all of the other AMQP libraries. I would also guess that this might be more common than confirming message delivery which has also been recently added to the amqp-messenger component.

Yes, it is possible to manually configure RabbitMQ with these bindings. This isn't exactly the best idea though. When you have an application that runs in development, staging, and production these bindings and other RabbitMQ configuration options can be easily stored in a config file to be applied on any environment needed. They also have a commit history for other developers to see what was changed. Having these as config values follows the same reasoning as using migration files to apply SQL changes to the database rather than manually applying them by hand.

Thanks for your time!

Copy link
Member

@Nyholm Nyholm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm. I see the previous discussions in #37722. Thank you.

When Im looking at the implementation I do like the fact that we only modify the AMQP bridge part of the code and that we not putting logic in the FrameworkBundle. I also agree with you that having config in version control makes sense. However, the Messenger component is not the only place to put infrastructure config =)

Im am convinced that a majority of people (more that 50% of AMQP users) do NOT use this feature, even though you claim it is very common.

I see that others have upvoted your original PR. Im going to try to give this a review and some testing later.

if (\is_array($queue['bindings'] ?? false)) {
foreach ($queue['bindings'] as $title => $individualBinding) {
if (0 < \count($invalidBindingsOptions = array_diff(array_keys($individualBinding), self::AVAILABLE_BINDINGS_OPTIONS))) {
throw new \InvalidArgumentException(sprintf('Invalid bindings option(s) "%s" passed to the AMQP Messenger transport in "%s". Each "bindings" option only accepts "key" and "arguments"', implode('", "', $invalidBindingsOptions), $title));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we say something like "Valid options for each 'bindings' are: %s", implode('", ", self::AVAILABLE_BINDINGS_OPTIONS?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, it's been updated.

'binding_keys',
'binding_arguments',
'flags',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will all DSN strings that work in 5.1 still work after merging this PR?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this is fully backwards compatible. Only deprecation notices are introduced for the binding_keys and binding_arguments.

@inferont inferont requested a review from Nyholm October 9, 2020 20:22
Copy link
Author

@inferont inferont left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Nyholm Please see my updates.

'binding_keys',
'binding_arguments',
'flags',
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this is fully backwards compatible. Only deprecation notices are introduced for the binding_keys and binding_arguments.

if (\is_array($queue['bindings'] ?? false)) {
foreach ($queue['bindings'] as $title => $individualBinding) {
if (0 < \count($invalidBindingsOptions = array_diff(array_keys($individualBinding), self::AVAILABLE_BINDINGS_OPTIONS))) {
throw new \InvalidArgumentException(sprintf('Invalid bindings option(s) "%s" passed to the AMQP Messenger transport in "%s". Each "bindings" option only accepts "key" and "arguments"', implode('", "', $invalidBindingsOptions), $title));
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, it's been updated.

@nicolas-grekas nicolas-grekas added this to the 5.x milestone Oct 12, 2020
@fabpot fabpot modified the milestones: 5.4, 6.1 Nov 16, 2021
@fabpot fabpot modified the milestones: 6.1, 6.2 May 20, 2022
@fabpot
Copy link
Member

fabpot commented Aug 7, 2022

Based on @Nyholm's comments, and the lack of traction for this feature, it may be better to close it.

@nicolas-grekas nicolas-grekas modified the milestones: 6.2, 6.3 Nov 5, 2022
@githoober
Copy link

@sroze , @Nyholm,

Hi everyone,

There is still interest in merging this PR. I have updated it and made sure its tests are passing. But I am getting the following error that I don't fully understand.

image


Would you be able to point me in the right direction?

Thanks.

@githoober
Copy link

I understand that the PHPUnit tests that are failing right now are failing because of deprecation warnings. How can this be fixed?

@nicolas-grekas nicolas-grekas modified the milestones: 6.3, 6.4 May 23, 2023
@nicolas-grekas nicolas-grekas modified the milestones: 6.4, 7.1 Nov 15, 2023
@xabbuh xabbuh modified the milestones: 7.1, 7.2 May 15, 2024
@fabpot fabpot modified the milestones: 7.2, 7.3 Nov 20, 2024
@fabpot fabpot modified the milestones: 7.3, 7.4 May 26, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Messenger] amqp-messenger does not allow a queue to have more than one binding
7 participants