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] add a transport that processes messages on kernel.terminate#28746

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

Closed
gonzalovilaseca wants to merge1 commit intosymfony:masterfromgonzalovilaseca:gv-28646
Closed

Conversation

@gonzalovilaseca
Copy link
Contributor

@gonzalovilasecagonzalovilaseca commentedOct 5, 2018
edited
Loading

QA
Branch?master
Bug fix?no
New feature?yes
BC breaks?no
Deprecations?no
Tests pass?yes
Fixed tickets#28646
LicenseMIT
Doc PR

I'm not sure if this is what Nicolas was asking for in this issue:#28646 (comment)
If it is, there are some questions that need general consensus:

  • Is it worth splitting this file into a listener and a handler and inject the handler in the listener?
  • Should the listener be in messenger component, in framework bundle or where?
  • Should the service definition: eg: tags for being processed as a handler and as an event subscriber be documented and configured manually by the user or should we put some kind of automation in place?

@gonzalovilaseca
Copy link
ContributorAuthor

(Deprecation label should be removed BTW)

@sroze
Copy link
Contributor

I think the approach of having a decorated handler might not be the best. What aboutusing a transport for this?

ogizanagi, gonzalovilaseca, and chalasr reacted with thumbs up emoji

@chalasrchalasr changed the title#28646 [Messenger] add a handler that processes messages on kernel.terminate[Messenger] add a handler that processes messages on kernel.terminateOct 8, 2018
@gonzalovilaseca
Copy link
ContributorAuthor

@sroze Not sure if I got it right....is this the right approach? If it is, I'll create tests, documentation etc.

@ogizanagi
Copy link
Contributor

ogizanagi commentedOct 11, 2018
edited
Loading

Just for the sake of completeness, here is the whole workflow to me:

  1. A message routed to thekernel.terminate transport is dispatched.
  2. TheSendMessageMiddleware gets the associated transport and send the message
  3. KernelTerminateTransport::send() stores the message to be treated later.
  4. If an exception occurs during the request, akernel.exception listener clears the spool of messages, so none are handled.
  5. Onkernel.terminate,KernelTerminateTransport::flush() is executed,
    which callsKernelTerminateTransport::receive() with thecallable $handler(?Envelope $envelope) argument:
    • adding aReceivedMessage item to the envelope so the message is not sent again by theSendMessageMiddleware
    • dispatching it to the bus.
  6. KernelTerminateTransport::receive() loops over stored messages and call$handler for each of them. Thus, each message is dispatched to be finally handled.

I'm just not sure about 4. Perhaps it should be configurable at the transport level as an option.

gonzalovilaseca and sroze reacted with thumbs up emoji

@nicolas-grekasnicolas-grekas added this to thenext milestoneOct 14, 2018
;

if ('symfony://kernel.terminate' ===$transport) {
$transportDefinition->addTag('kernel.event_listener',array('event' => KernelEvents::TERMINATE));
Copy link
Contributor

Choose a reason for hiding this comment

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

Can't you take the event from what is aftersymfony:// instead of hardcoding it?

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

Does it make sense if we're only going to listen to that event?

Copy link
Contributor

Choose a reason for hiding this comment

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

See comments after#28646 (comment).
I'm not convinced another use-case should be provided out-of-the-box by the Framework bundle.

@nicolas-grekas
Copy link
Member

See#28646 (comment) for more thoughts on this.

@gonzalovilaseca
Copy link
ContributorAuthor

I've updated the PR as per the comments (hope I understood all comments correctly...).
I'd like to ask for feedback on this issues:

  1. I'd splitMemoryTransport into 2 classesMemoryTransport andSymfonyKernelEventTransport, the second one will containMemoryTransport plus the 2 kernel listener methods.
  2. I also need to pass the bus to the memory transport but I'm not sure what's the best way to achieve it, it could be defined in the transport options, but then I'd need to inject it into the factory insrc/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php, the factory would then inject it in the memory transport. Any better way?

@gonzalovilaseca
Copy link
ContributorAuthor

BTW does anyone have a sandbox project I could use to test this functionality?

@gonzalovilasecagonzalovilaseca changed the title[Messenger] add a handler that processes messages on kernel.terminate[Messenger] add a transport that processes messages on kernel.terminateOct 28, 2018
@gonzalovilaseca
Copy link
ContributorAuthor

@sroze@nicolas-grekas@ogizanagi Have updated the PR with suggestions given, it's not ready to review yet as it's not complete, but would like some feedback to check if I'm in the right direction before doing the final work.
Thanks!

@ogizanagi
Copy link
Contributor

@gonzalovilaseca : Sorry for the lack of answer.

I also need to pass the bus to the memory transport but I'm not sure what's the best way to achieve it

I think the factory should be aware of all the available buses, by injecting a service locator. Then, a transport option should allow the factory to select the right bus by its key.

@gonzalovilaseca
Copy link
ContributorAuthor

@gonzalovilaseca : Sorry for the lack of answer.

I also need to pass the bus to the memory transport but I'm not sure what's the best way to achieve it

I think the factory should be aware of all the available buses, by injecting a service locator. Then, a transport option should allow the factory to select the right bus by its key.

Can you check what I've done insrc/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php? I've just defined an alias for the chosen bus, it would make sense to inject a service locator if the transport was able to use more than one, I think it's easier WDYT?

@ogizanagi
Copy link
Contributor

ogizanagi commentedOct 28, 2018
edited
Loading

You may have more than one of such transport. For instance one per bus. The factory would be used to create each of these then (so it needs to know every buses).

@gonzalovilaseca
Copy link
ContributorAuthor

updated!

@gonzalovilaseca
Copy link
ContributorAuthor

@sroze@nicolas-grekas@ogizanagi Are we happy with this as it is, so I can start writing tests?

Copy link
Contributor

@ogizanagiogizanagi left a comment

Choose a reason for hiding this comment

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

Looks good (to me) yes :)

@gonzalovilaseca
Copy link
ContributorAuthor

Updated!

@ogizanagi
Copy link
Contributor

ogizanagi commentedOct 31, 2018
edited
Loading

@gonzalovilaseca: I hope you won't mind me, but I've rebased and pushed some changes to your branch hopefully fixing@sroze's review and some other tweaks I've spotted during this operation :)

gonzalovilaseca reacted with thumbs up emoji

->addTag('messenger.receiver',array('alias' =>$name))
;

if (0 ===strpos($transport['dsn'],'symfony://kernel.terminate')) {
Copy link
Contributor

@ogizanagiogizanagiOct 31, 2018
edited
Loading

Choose a reason for hiding this comment

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

Hmm. I just realized this won't work with env vars.
As I don't see any use-cases for it, it may be fine, but we need extra pov.
If we want to support it, the kernel terminate transport factory will need the event dispatcher and add listeners itself (still, that would be a better implementation and give the factory even more sense?).

(Note the same goes for theamqp:// check above, but it's only about a hint for the developper)

@gonzalovilaseca
Copy link
ContributorAuthor

@ogizanagi@sroze I've updated the PR with tests

@ogizanagi
Copy link
Contributor

@gonzalovilaseca : Great! :)

But I think we need to treat#28746 (comment). Consistency is the key, this transport dsn should work as an env var as any other.
The default recipe suggests aMESSENGER_TRANSPORT_DSN env var that one may use asMESSENGER_TRANSPORT_DSN=symfony://kernel.terminate.
This means the factory must register the event listener itself at runtime, not the extension.

Regarding#29097 (comment), I also think we should extract the re-dispatching logic out of theMemoryTransport, which would just keep messages in memory, no more. So thenull:// transport would just be a different factory.
But this last point could be done in a next PR, as we have time to iterate over this feature.

*/
publicfunctionstop():void
{
$this->envelopes =array();
Copy link
Contributor

Choose a reason for hiding this comment

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

Instead of emptying, we may just use a$stopped flag used in receive to skip handling as in

so we keep envelopes list on exception, but don't re-dispatch them.

@gonzalovilaseca
Copy link
ContributorAuthor

Can an event be registered at runtime? (I thought that wasnt possible as the container is already compiled)

@ogizanagi
Copy link
Contributor

Sure. You'll need to inject the@event_dispatcher in the factory, and useEventDispatcher::addListener.
The container being already compiled just means we won't see the tagged service definition usingdebug:container (nordebug:event-dispatcher unless the factory is called before).

@gonzalovilaseca
Copy link
ContributorAuthor

Ok cool, will do that then.

@gonzalovilaseca
Copy link
ContributorAuthor

@ogizanagi updated following suggestions

publicfunctionflush():void
{
$this->receive(function (Envelope$envelope) {
if (null ===$envelope) {
Copy link
Contributor

Choose a reason for hiding this comment

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

$envelope can not benull here, because of the type hint.

$transport =newMemoryTransport($this->busLocator->get($busId));

$this->eventDispatcher->addListener(KernelEvents::TERMINATE,array($transport,'flush'));
$this->eventDispatcher->addListener(KernelEvents::EXCEPTION,array($transport,'stop'));
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we also have to add listeners to the corresponding console events?Like in swiftmailer-bundle for the memory spool?

@gharlan
Copy link
Contributor

Any chance to get this merged into 4.3? (feature freeze is in two weeks)
How can I help?

@gonzalovilaseca
Copy link
ContributorAuthor

It's just waiting for review..

@sroze
Copy link
Contributor

Thank you very much for your efforts on this pull-request@gonzalovilaseca. Now that we have other transports (Doctrine especially) I think that the risks associated with such transport are too high:as mentioned by @fabpot ealier, running things onkernel.terminate are making things very hard to debug because you won't be able to see the errors (if some happen), even in development, nor be able to benefit from the retry mechanism that has been introduced.

Let's close this so we push everybody to use more reliable solutions 🚀

@nicolas-grekas
Copy link
Member

nicolas-grekas commentedApr 6, 2019
edited
Loading

Sorry for making you work on this, but even if it wasn't merged, it helped a lot moving things forward! So thank you!

@nicolas-grekasnicolas-grekas modified the milestones:next,4.3Apr 30, 2019
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

@OskarStarkOskarStarkOskarStark requested changes

+4 more reviewers

@gharlangharlangharlan left review comments

@srozesrozesroze requested changes

@ogizanagiogizanagiogizanagi requested changes

@stloydstloydstloyd requested changes

Reviewers whose approvals may not affect merge requirements

Assignees

No one assigned

Projects

None yet

Milestone

4.3

Development

Successfully merging this pull request may close these issues.

9 participants

@gonzalovilaseca@sroze@ogizanagi@nicolas-grekas@gharlan@stloyd@OskarStark@chalasr@carsonbot

[8]ページ先頭

©2009-2025 Movatter.jp