Skip to content
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

always declare a queue in factory, even with auto_setup_fabric disabled #61

Merged
merged 12 commits into from
Mar 3, 2018

Conversation

prolic
Copy link
Owner

@prolic prolic commented Nov 25, 2017

alternative solution to #57

ping @oqq

@prolic prolic changed the title always declare a queue always declare a queue in factory, even with auto_setup_fabric disabled Nov 25, 2017
@coveralls
Copy link

coveralls commented Nov 25, 2017

Coverage Status

Coverage remained the same at 92.686% when pulling a8b83e7 on declare_queue into 73a777b on master.

Copy link
Contributor

@oqq oqq left a comment

Choose a reason for hiding this comment

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

Maybe add a purge command for rabbitmq before each test to test every branch separated. Random queue/exchange names could also work therefor.

@@ -163,8 +163,6 @@ public function __invoke(ContainerInterface $container): Queue
$exchangeObjects[$exchange] = ExchangeFactory::$exchange($container, $this->channel, true);
}

$queue->declareQueue();
Copy link
Contributor

Choose a reason for hiding this comment

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

This would potentially fail, if auto_setup_fabric is true, since you would bind a queue to an exchange which is not declared.

@prolic
Copy link
Owner Author

prolic commented Dec 16, 2017 via email

@oqq
Copy link
Contributor

oqq commented Dec 16, 2017

Sorry, I expressed it badly.

You create an exchange and bind the queue to the exchange. And than you create the queue.
This would fail, since the queue would be bound to the exchange before the queue exists.

Currently, the tests doesn't fail, while you create the queue in another test. So every test should purge the whole rabbitmq queues/exchanges before run.

@prolic
Copy link
Owner Author

prolic commented Dec 16, 2017 via email

@prolic
Copy link
Owner Author

prolic commented Dec 17, 2017

@oqq good to release now?

@coveralls
Copy link

coveralls commented Dec 17, 2017

Coverage Status

Coverage decreased (-1.4%) to 91.299% when pulling d1da5f2 on declare_queue into 73a777b on master.

@oqq
Copy link
Contributor

oqq commented Dec 19, 2017

That seems not to be enough to fix the issue.
All queues where be created how expected. But the exchange binding would not happen.

So given for an exclusive rpc queue, the queue would be created but never be bind to an exchange. I still have to set auto_setup_fabric, but this would also create the exchange, which already exists on the broker with a configuration I am not always aware about.

@prolic
Copy link
Owner Author

prolic commented Dec 23, 2017

ping @oqq - wanna check this?

@coveralls
Copy link

coveralls commented Dec 23, 2017

Coverage Status

Coverage decreased (-1.4%) to 91.304% when pulling 2c48ecb on declare_queue into 73a777b on master.

$exchanges = iterator_to_array($exchanges);
}

if (! is_array($exchanges) || empty($exchanges)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

It should not be necessary for this library to bind a queue to an exchange.
E.g. a service which purges queues (or handles other tasks) needs only to know the queue name, but not the name of the exchange.

$bindArguments = $exchangeOption['bind_arguments'] ?? [];
$this->bindQueue($queue, $exchangeName, $routingKeys, $bindArguments);
}
$exchangeObjects[$exchange] = ExchangeFactory::$exchange($container, $this->channel, false);
Copy link
Contributor

Choose a reason for hiding this comment

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

Here my advice for a code cleanup:

$autoSetupFabric = $this->autoSetupFabric || $options['auto_setup_fabric'];

if ($autoSetupFabric && isset($options['arguments']['x-dead-letter-exchange'])) {
    $exchangeName = $options['arguments']['x-dead-letter-exchange'];
    ExchangeFactory::$exchangeName($container, $this->channel, true);
}

foreach ($exchanges as $exchange => $exchangeOptions) {
    $exchangeObjects[$exchange] = ExchangeFactory::$exchange($container, $this->channel, $autoSetupFabric);
}

@prolic
Copy link
Owner Author

prolic commented Dec 31, 2017 via email

@oqq
Copy link
Contributor

oqq commented Dec 31, 2017

This factory is not used only for anonymous queues, or is it?

But I see also a service wich simply calls some amqp methods on an anonymous queue which already exists, without knowing her exchange bindings. This would be impossible to implemented with this library if I always need to define exchanges.

This would be a BC break by the way. ;)

@prolic
Copy link
Owner Author

prolic commented Jan 2, 2018

@oqq I'm thinking about this solution:

  • only if queue has no name (anonymous queue) then we require exchange binding and do the binding, even if auto_setup_fabric is set to false
  • in all other cases the exchange binding is not needed

Additional I have another thought on auto_setup_fabric considering queues... current behaviour is, that the exchanges are also getting created. Maybe we remove this feature and add another option auto_setup_exchanges => true/false additionally to the queue factory.

As this is a bigger problem here which leads to unexpected errors, I'm ok with slightly breaking BC and will update docs/ release notes accordingly.

@prolic
Copy link
Owner Author

prolic commented Feb 6, 2018

@oqq Sorry for taking so much time, I think the new behaviour here is good, I also updated the readme. Can you check please?

@prolic
Copy link
Owner Author

prolic commented Feb 25, 2018

ping @oqq

@oqq
Copy link
Contributor

oqq commented Mar 3, 2018

@prolic this would still produce errors, if you try to bind a queue to an exchange before declaring it.
You call bindQueue() always before declareQueue(), which produces this error:

operation queue.bind caused a channel exception not_found: "no previously declared queue"

@prolic
Copy link
Owner Author

prolic commented Mar 3, 2018

@oqq updated

@oqq
Copy link
Contributor

oqq commented Mar 3, 2018

I have an application with a complex infrastructure and all tests run successfully with this patch. So I assume this would fix the issue.

Thanks!

@prolic prolic merged commit 45b7037 into master Mar 3, 2018
@prolic prolic deleted the declare_queue branch March 3, 2018 13:40
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.

3 participants