How to receive a response in the client after immediate retries

Hello,
We send a message through a nservicebus from web API to the worker service.
We use such a retry policy:
Number of immediate retries: 5
Number of delay retries: 5
Interval for delay retries: 2 min

Right now, if there is an error in the service that will not be fixed in immediate retries, the client will wait until the timeout (30 sec for REST). After that, if the message will be successfully processed during delayed retry, nservicebus will try to deliver a message to the client and there will be an error “No handlers could be found for message type”, since the client has already received a timeout message.

We don’t really like this behavior. Is there a way to get the response on the client right after all the immediate retries? We would still like the deferred replays to continue to work.

Hi @ElenaShlykova

I’m not sure I fully understand the system based on your description, so please correct me if my understanding is wrong: You do have an webserver that receives HTTP requests from clients and sends messages triggered by those requests to a worker service. I assume the worker service sends a reply upon completion to the web server, which then sends finishes the in-progress HTTP request. Is that understanding correct?

Is there a way to get the response on the client right after all the immediate retries?

what kind of response would you like to send to the client in that case? Are you primarily interested in being “notified” if all immediate retries have been exceeded?

That is correct.
There are 2 goals:

  1. Messages that come from WebApi should not end in the error queue with “No handlers could be found for message type” error in case of timeout for HTTP client
  2. We want to receive an exception for request in WebApi if immediate retries have been exceeded

Your first goal should be achievable using a custom recoverability policy that discards failed messages with that exception. You can read more about custom recoverability policies here: Custom Recoverability Policy • NServiceBus • Particular Docs.

However, I don’t think the second goal is easy to achieve as there is no information available to other endpoints about the recoverability behavior of an endpoint. There are some events available to a specific endpoint to use, but you’d still have to deal with the challenge to get that information back to the web server and let that cancel the HTTP operation from the client.

Instead of trying to make this work using the approach you described, I think this is a situation where messaging might not be an ideal pick based on your requirements. Messaging is not an ideal tool if you need to have fast request-reply behavior that is not relevant anymore after a short amount of time. Although I’m not familiar with your specific projet of needs, I’d recommend the following options instead:

  • Use HTTP requests (or some other protocol suitable) instead to your server endpoint to handle the request and provide the response information. This way, it is much easier to react to timeouts and discard responses if needed. Given your described interaction already requires the backend webserver to be available to complete the process, using a synchronous request does not really matter.
  • Redesign the process so that it can make better use of the benefits of messaging. A common approach in these cases is to send the message to server with a specific ID assigned to the request. The web server can immediately respond back to the client and provide the generated ID to the client as the client can be assured that the request will be handled at some point and is safely handed over to the queuing system. The client can then check the status of the requested operation and receive the requested results once available via the provided ID from the first request. This is a better approach for processes that might take longer to complete or that want to ensure temporal decoupling from the backend.
1 Like