Nservicebus: Notification delegates should provide message session to the callbacks

Created on 11 Aug 2018  路  6Comments  路  Source: Particular/NServiceBus

NServiceBus Notifications delegates invoke callbacks passing in two arguments: sender (ErrorsNotifications) and message (FailedMessage, DelayedRetryMessage, or ImmediateRetryMessage).

Often Notifications are used to subscribe and dispatch some work based on type of notification using IMessageSession. Some customers isolate this kind of "wire and forget" work in a self-contained assembly and deploy to multiple endpoints w/o any configuration requried.

With NServiceBus version 5 IBus exposed Notifications and Send() operation. With a separation of configuration-time and run-time, two pieces are needed to achieve what was possible prior to version 6.

Unfortunately, to retrieve IMessageSession in addition to Notifications is not an easy task outside of self-hosted scenario. For example: when using NServiceBus host or NServiceBus Features. It also forces to take a depencency on IMessageSession that should be available in Core when a notification is generated and could be passed into the callback. This would require callbacks signature change from
(object sender, FailedMessage message) to (object sender, FailedMessage message, IMessageSession session), but would eliminate the complexity of dispatching when a notification is received.

Reference: support case

Most helpful comment

tbh I'm not a big fan of the idea of sprinkling IMessageSession over every API which potentially wants to send a message though (that basically means every single public API which provides/accepts some sort of callback and doesn't already provide a session/context). Thoughts?

All 6 comments

Unfortunately, to retrieve IMessageSession in addition to Notifications is not an easy task outside of self-hosted scenario.

It sounds to me like this is the more general, broader problem instead which doesn't relate directly to the Notifications?

Notifications happened to be what I was helping a customer with.
I tend to agree that whenever there's information that could be turned into a message, having core to provide IMessageSession rather than user figuring out how to inject it would be nice. It would reduce complexity in the customer maintainer code and be aligned with the concept of context we've introduce back in V6.

tbh I'm not a big fan of the idea of sprinkling IMessageSession over every API which potentially wants to send a message though (that basically means every single public API which provides/accepts some sort of callback and doesn't already provide a session/context). Thoughts?

Let me clarify, I am not saying we should have IMessageSession _everywhere_. It should be done where it needs to be. Raised this specific issue for Notifications. Wherever there's a broader problem or not, I'll defer to core maintainers.

I think we have to evaluate this on a per use case basis.

In this case do we believe that is is a use case for sending message from the error notifications?

errors.MessageHasBeenSentToDelayedRetries

In this case we're retrying the message, is there really a use case to send some message, likely back to the sending endpoint to report that we're retrying?

I've seen users ask for this but I'm on the fence

Note: Since we're actually committing the receive transaction this can likely be made consistent with the receive operation. That said some transports rollback first to clear any pending stuff which would mean that we would have to store this message to be able to "re-submitt" it or make it fire and forget. Passing in the message session would make it fire and forget unless TX Scopes are in play

errors.MessageHasFailedAnImmediateRetryAttempt

Same as above, but feels even less relevant, we're doing a few quick retris, users shouldn't care?

errors.MessageSentToErrorQueue

This seems to be the interesting one, since now the message will go to the error queue and will sit there until manual action is taken. Is there some use cases around this? That said we have SC events that cater for this in a more robus way. Ie hook up to https://docs.particular.net/servicecontrol/contracts and update your status cache/whatever

@SeanFeldman do you have more detail regarding what the user was trying to achieve?

I've updated support case link (it was broken).
The case was about upgrading from v5 to v6, and the issue with missing IBus option where it was available before. One of their use cases was automation of reporting failed message using IBus and `Notifications by distributing a single assembly that has automated the process for them.

Back then I did not think about SC and subscribing MessageFailed event. Will follow up with the customer to clarify if that was an option. Unless they don't use SC at all.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

tmasternak picture tmasternak  路  6Comments

SimonCropp picture SimonCropp  路  6Comments

andreasohlund picture andreasohlund  路  8Comments

WilliamBZA picture WilliamBZA  路  10Comments

WojcikMike picture WojcikMike  路  5Comments