Skip to content

[Messenger] Pass sender details to SendMessageToTransportsEvent #40152

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

Merged
merged 1 commit into from
Aug 19, 2022

Conversation

Jeroeny
Copy link
Contributor

@Jeroeny Jeroeny commented Feb 11, 2021

Q A
Branch? 6.1
Bug fix? no
New feature? yes
Deprecations? no
License MIT

This is a feature suggestion that will allow listeners for SendMessageToTransportsEvent to be able to read the sender and sender alias from a sent message.

Use case: To create metrics for messages that go through the system (and especially where to and from). Listener(s) can be created to measure this. They would listen to WorkerMessageHandledEvent, WorkerMessageFailedEvent and SendMessageToTransportsEvent. The first two receive envelopes that contain a ReceivedStamp, to determine where the message came from. However, the received envelopes for sent messages do not contain a stamp to read the sender. It would be great if this was possible to do with listener (instead of having to add middleware to each bus).

Approach in this PR: stamp the envelope with SentStamp before dispatching SendMessageToTransportsEvent.

Alternative approach: pass the info to the event directly: new SendMessageToTransportsEvent($envelope, get_class($sender), $alias). And keep the stamping afterwards.

Edit: I just noticed that one event is dispatched regardless of the number of senders. In that case the event could be dispatched after all the senders have been called (and thus all the stamps set).

@carsonbot
Copy link

Hey!

I had a quick look at this PR, I think it is alright.

I think @ruudk has recently worked with this code. Maybe they can help review this?

Cheers!

Carsonbot

@nicolas-grekas nicolas-grekas added this to the 5.x milestone Feb 16, 2021
Copy link
Contributor

@ruudk ruudk left a comment

Choose a reason for hiding this comment

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

The SendMessageToTransportsEvent is about sending to one or multiple transports (hence plural transports).

The SentStamp is past tense, meaning it's already sent. When you would pass that to the subscribers listening on SendMessageToTransportsEvent that would be untrue, as the message is not sent yet.

It's different to the ReceivedStamp passed to the worker subscribers, in those cases, the message is actually received.

Therefore I think it would be better to do the following:

$senders = $this->sendersLocator->getSenders($envelope);
if (null !== $this->eventDispatcher) {
    $event = new SendMessageToTransportsEvent($envelope, $senders);
    $this->eventDispatcher->dispatch($event);
    $envelope = $event->getEnvelope();
}
foreach ($senders as $alias => $sender) {
    $this->logger->info('Sending message {class} with {alias} sender using {sender}', $context + ['alias' => $alias, 'sender' => \get_class($sender)]);
    $envelope = $sender->send($envelope->with(new SentStamp(\get_class($sender), \is_string($alias) ? $alias : null)));
}

This way:

  • you still only emit 1 event
  • the event now contains all the senders
  • the envelope passed to the subscribers is still the same

@fabpot fabpot modified the milestones: 5.4, 6.1 Oct 30, 2021
@Jeroeny
Copy link
Contributor Author

Jeroeny commented Nov 30, 2021

@ruudk sendersLocator->getSenders() returns iterable (sometimes a \Generator). I tried your suggestion, but loading all the senders and aliases into an array got a bit complex. I agree that there's still some improvement to gain here though.

@fabpot fabpot modified the milestones: 6.1, 6.2 May 20, 2022
@fabpot
Copy link
Member

fabpot commented Aug 9, 2022

What's the status of this PR? @Jeroeny Are you still interested in moving it forward?

@Jeroeny
Copy link
Contributor Author

Jeroeny commented Aug 9, 2022

Yes I'd be willing to move this forward. The last time I hit kind of a dead-end in which approach to take. Would ruudk's suggestion be desired for example?

@fabpot
Copy link
Member

fabpot commented Aug 9, 2022

I think @ruudk's suggestion makes a lot of sense.

@Jeroeny
Copy link
Contributor Author

Jeroeny commented Aug 9, 2022

In their snippet, $senders is usually a \Generator. To pass it to SendMessageToTransportsEvent, should this be converted to an array (losing the aliases or risk of losing entries due to duplicate array-keys which Generators allow) ? Or be passed as-is, which will cause problems when reading the variable, because the sending logic will not get those values from the Generator too ? Or call getSenders() twice, which also seems undesirable.

@fabpot
Copy link
Member

fabpot commented Aug 14, 2022

What would be the use case for having two entries with the same alias?

@Jeroeny
Copy link
Contributor Author

Jeroeny commented Aug 16, 2022

I don't think there is, but I thought it was technically supported and could cause issues. Anyway, I've implemented the suggested approach 👍 .

@fabpot
Copy link
Member

fabpot commented Aug 19, 2022

Thank you @Jeroeny.

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.

5 participants