NServiceBus
NServiceBus copied to clipboard
Request/Response pattern not working well for failure
A lot of users do request/response over messaging and sometimes a response must be send to indicate "failure with a reason".
- If it was due to an exception, you basically need to do a "Reply" with immediate dispatch and
throw
to prevent side effects as otherwise the transaction of any storage/transport is not rolled back. - Due to recovery the same message will be processed again, meaning that multiple failures are sent back or maybe even the 2nd attempt is successful. For such operations you want to suppress recovery for a specific handler then we have the problem that multiple handlers/sagas can be invoked.
It is a difficult problem to solve with our current APIs and message processing behavior.
There are customers:
- Hooking into our events to send back 'failure responses'. Disconnecting the 'response' logic from the handler logic.
- Doing this using our gateway.
@ramonsmits we (during a grooming session with @lailabougria) looked at this from the angle of guidance, and we were wondering why would you want to throw
? Isn't it better to simply consider the incoming message as successfully handled?
So the flow would be something like:
- process incoming message;
- detect failure (e.g. try/catch)
- log if you wish
- reply with a "failure"-kind of response
- ack the incoming message (and never throw)
More context: https://milestone.topics.it/2019/09/10/businesses-dont-fail-they-make-mistakes.html
I think there is value in an api change to enable what you are proposing. I think this should be considered when we do a callbacks package enhancement release.
Something like:
var result = context.Request<ResponseType>(message, onError).ConfigureAwait(false);
Where onError would be called if the handler failed. Or maybe a throw or something - I don't know. That taskforce dealing with the enhancement release can decide the most appropriate API and behaviour.
It's likely that when processing a message from a request that the handler should have recoverability disabled too.