Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

[Messenger] make senders and handlers subscribing to parent interfaces receive *all* matching messages, wildcard included#29010

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
sroze merged 1 commit intosymfony:masterfromnicolas-grekas:messenger-no-chain
Oct 31, 2018

Conversation

@nicolas-grekas
Copy link
Member

@nicolas-grekasnicolas-grekas commentedOct 28, 2018
edited
Loading

QA
Branch?4.2
Bug fix?no
New feature?yes
BC breaks?yes
Deprecations?no
Tests pass?yes
Fixed tickets-
LicenseMIT
Doc PR-

Embeds#29006 for now.

From the CHANGELOG:

  • senders and handlers subscribing to parent interfaces now receiveall matching messages, wildcard included
  • HandlerLocatorInterface::resolve() has been removed, useHandlersLocator::getHandlers() instead
  • SenderLocatorInterface::getSenderForMessage() has been removed, useSendersLocator::getSenders() instead
  • TheChainHandler andChainSender classes have been removed
  • TheContainerHandlerLocator,AbstractHandlerLocator,SenderLocator andAbstractSenderLocator classes have been removed

The newHandlersLocatorInterface andSendersLocatorInterface interfaces returniterable of corresponding handlers/senders. This allows simplifying a lot the DI configuration and standalone usage.

Inheritance-based configuration is now stable: when a sender or a handler is bound toSomeMessageInterface, it will always get all messages of that kind. This fixes the unstable nature of the previous logic, where only the first matching type bound to a message would match, making routing/handling unpredictable (note that the new behavior is also how Laravel does it.)

Some cleanups found meanwhile:

  • themessenger.sender tag was useless, it's removed
  • the reponsibility of the "send-and-handle" decision has been moved to the locator, where it belongs
  • thanks to type+argument autowiring aliases, we don't need to force defining a default bus - gaining nice errors when a named argument has a typo
  • some services have been renamed to make them more conventional

As far as priorities are concerned, the priority number applies in the scope of the type bound to it: senders/handlers that are bound to more specific types are always called before less specific ones, no matter the defined priority.

skalpa, weaverryan, yceruto, ro0NL, and sroze reacted with heart emoji
@nicolas-grekas
Copy link
MemberAuthor

@topbin thanks, fixed

Copy link
Contributor

@ro0NLro0NL left a comment

Choose a reason for hiding this comment

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

thanks to type+argument autowiring aliases, we don't need to force defining a default bus

so potentially MessageBusInterface has no alias? currently the "message_bus" is still forced to exists few line down low.

@nicolas-grekas
Copy link
MemberAuthor

currently the "message_bus" is still forced to exists few line down low

fixed

@ro0NL
Copy link
Contributor

MessengerPass wont run if there's no message_bus service, its' not needed anymore IIUC (fixes#28959 i guess :))

@nicolas-grekas
Copy link
MemberAuthor

MessengerPass wont run if there's no message_bus service

fixed - and also fixed the message in ControllerTrait.

@weaverryan
Copy link
Member

This is the approach I was absolutely hoping for. It's predicatable, but type-based. Awesome!

skalpa reacted with thumbs up emoji

@skalpa
Copy link
Contributor

skalpa commentedOct 29, 2018
edited
Loading

Wouldn't it be worth removing the handlers'priority altogether ? As it is now it's pretty confusing as it only sorts handlers that subscribe to the same type.

It made sense when the handler with the highest priority used towin, but a lot less now. IMHO, users should not expect handlers to be executed in a predictable order. If one needsBarHandler to be executed afterFooHandler, then they shouldn't both subscribe to the same message type:FooHandler should dispatch an additional message thatBarHandler will subscribe to.

@nicolas-grekas
Copy link
MemberAuthor

If a subscriber can declare its priority, it can also declare a more specific type to register. So that's not a downgrade in terms of possibilities. Then, within one type, it can be useful to have priorities (otherwise why would we have added them?) so I think it's OK as is.

@skalpa
Copy link
Contributor

Honestly, I wouldn't know why priorities were added to start with ;-). Anyway, I'm fine with that, and this behavior can always be documented.
Btw, all your latest PRs on this component have been brilliant, thanks a lot.

nicolas-grekas reacted with heart emoji

@Tobion
Copy link
Contributor

Tobion commentedOct 29, 2018
edited
Loading

IMHO, users should not expect handlers to be executed in a predictable order. If one needs BarHandler to be executed after FooHandler, then they shouldn't both subscribe to the same message type

Fully agree with@skalpa . You can also make it one handler that does the right thing internally. Also since priortiy now has a different meaning than before, I would suggest to remove it.

@nicolas-grekas
Copy link
MemberAuthor

nicolas-grekas commentedOct 29, 2018
edited
Loading

For message buses, priorities can be useless, but the component should also work for query buses. In this case, priorities could be important to have. I expect people to use flat message types most of the time also.

@nicolas-grekas
Copy link
MemberAuthor

PR rebased, ready to merge.

if (($definition =$container->findDefinition($messengerMiddlewareId))->isAbstract()) {
$childDefinition =newChildDefinition($messengerMiddlewareId);
$count =\count($definition->getArguments());
foreach (array_values($arguments ??array())as$key =>$argument) {
Copy link
MemberAuthor

Choose a reason for hiding this comment

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

all this logic should be removed: ChildDefinition already have their merging logic. Overwriting an existing parent argument is done by usingindex_0 as a key. Let's make things simpler by reusing existing knowledge.

chalasr reacted with thumbs up emoji
));

$this->assertSame(array($sender),iterator_to_array($locator->getSenders(DummyMessage::class)));
$this->assertSame(array(),iterator_to_array($locator->getSenders(SecondMessage::class)));
Copy link
Contributor

@TobionTobionOct 30, 2018
edited
Loading

Choose a reason for hiding this comment

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

it's technically not safe to calliterator_to_array on the result as it's return type isiterable which can be an array. I usually have a helper function for cases like thisiterableToArray

Copy link
MemberAuthor

Choose a reason for hiding this comment

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

that's a test case: wedo expect an iterator. Even if it's implicit, at least it protects against changing the return value to an array.

sroze and ro0NL reacted with thumbs up emoji
Copy link
Contributor

Choose a reason for hiding this comment

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

Then that should be a new assertion. A static code analyzer would complain about this code.

$messagePriority =$messageClass[1];
$messageClass =$messageClass[0];
if (\is_array($message)) {
list($message,$priority) =$message;
Copy link
Contributor

Choose a reason for hiding this comment

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

this case is not documented and seems to be a relict of the old subscriber return values. considering all the bc breaks, this could be removed as well I guess.

Copy link
MemberAuthor

Choose a reason for hiding this comment

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

I'd suggest doing so in another PR - here it's unrelated (and I feel like this compiler pass needs to be improved anyway)

ogizanagi reacted with thumbs up emoji
returnarray($class =>$class,'*' =>'*');
}

returnarray($class =>$class)
Copy link
Contributor

Choose a reason for hiding this comment

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

The array key does not seem to be used or useful. So you could put anarray_values around the whole array union. This would clarify the code to me as it makes clear the array key is only relevant for the array union operation.

Copy link
Contributor

@TobionTobionOct 31, 2018
edited
Loading

Choose a reason for hiding this comment

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

return array_values(array($class => $class) + ...)

Copy link
MemberAuthor

Choose a reason for hiding this comment

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

An array_values() call would add memory and CPU overhead for no reason. Yes, we don't use the keys. That's not an issue to me - arrays always have keys anyway. And actually having the key be the values makes it impossible to return twice the same value, which is part of the contract of this function. I'd keep as is.


* The component is not experimental anymore
* All the changes below are BC BREAKS
* senders and handlers subscribing to parent interfaces now receive*all* matching messages, wildcard included
Copy link
Contributor

Choose a reason for hiding this comment

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

An upper case would be lovely here.

Copy link
Contributor

@srozesroze left a comment

Choose a reason for hiding this comment

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

Fantastic. Let's defo make that in 4.2.

…s receive *all* matching messages, wildcard included
@sroze
Copy link
Contributor

It took time, but here we go, this is in now. Thank you very much@nicolas-grekas.

@srozesroze merged commit1e7af4d intosymfony:masterOct 31, 2018
sroze added a commit that referenced this pull requestOct 31, 2018
…arent interfaces receive *all* matching messages, wildcard included (nicolas-grekas)This PR was merged into the 4.2-dev branch.Discussion---------- [Messenger] make senders and handlers subscribing to parent interfaces receive *all* matching messages, wildcard included| Q             | A| ------------- | ---| Branch?       | 4.2| Bug fix?      | no| New feature?  | yes| BC breaks?    | yes| Deprecations? | no| Tests pass?   | yes| Fixed tickets | -| License       | MIT| Doc PR        | -~Embeds#29006 for now.~From the CHANGELOG: * senders and handlers subscribing to parent interfaces now receive *all* matching messages, wildcard included * `HandlerLocatorInterface::resolve()` has been removed, use `HandlersLocator::getHandlers()` instead * `SenderLocatorInterface::getSenderForMessage()` has been removed, use `SendersLocator::getSenders()` instead * The `ChainHandler` and `ChainSender` classes have been removed * The `ContainerHandlerLocator`, `AbstractHandlerLocator`, `SenderLocator` and `AbstractSenderLocator` classes have been removedThe new `HandlersLocatorInterface` and `SendersLocatorInterface` interfaces return **`iterable`** of corresponding handlers/senders. This allows simplifying a lot the DI configuration and standalone usage.Inheritance-based configuration is now stable: when a sender or a handler is bound to `SomeMessageInterface`, it will always get all messages of that kind. This fixes the unstable nature of the previous logic, where only the first matching type bound to a message would match, making routing/handling unpredictable (note that the new behavior is also how Laravel does it.)Some cleanups found meanwhile: * the `messenger.sender` tag was useless, it's removed * the reponsibility of the "send-and-handle" decision has been moved to the locator, where it belongs * thanks to type+argument autowiring aliases, we don't need to force defining a default bus - gaining nice errors when a named argument has a typo * some services have been renamed to make them more conventionalAs far as priorities are concerned, the priority number applies in the scope of the type bound to it: senders/handlers that are bound to more specific types are always called before less specific ones, no matter the defined priority.Commits-------1e7af4d [Messenger] make senders and handlers subscribing to parent interfaces receive *all* matching messages, wildcard included
@nicolas-grekasnicolas-grekas deleted the messenger-no-chain branchOctober 31, 2018 08:05
@nicolas-grekas
Copy link
MemberAuthor

Awesome, thank you all for your help!

@bendavies
Copy link
Contributor

lots of cool changes to messenger - please don't forget about docs!

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

4 more reviewers

@TobionTobionTobion left review comments

@ro0NLro0NLro0NL left review comments

@ogizanagiogizanagiogizanagi left review comments

@srozesrozesroze approved these changes

Reviewers whose approvals may not affect merge requirements

Assignees

No one assigned

Projects

None yet

Milestone

4.2

Development

Successfully merging this pull request may close these issues.

9 participants

@nicolas-grekas@ro0NL@weaverryan@skalpa@Tobion@sroze@bendavies@ogizanagi@carsonbot

[8]ページ先頭

©2009-2025 Movatter.jp