Timeout on Bus.Send callback

257 views
Skip to first unread message

Steve Wilkinson

unread,
Dec 12, 2014, 6:54:01 AM12/12/14
to particula...@googlegroups.com
Helpful information to include
Product name: NServiceBus
Version: 5.1.1

Does anyone have an example of implementing a timeout when a callback is registered on Bus.Send ?  I effectively want to return an Http timeout status from a WebAPI method if no response from a handler is received or not received within a given amount of time.

We aren't using the bus to query for data, we are just talking about simple return codes here, a kind of acknowledgement.  I don't want to have to go down the route of using SignalR callbacks to the browser etc.

I know the whole request/response scenario sparks a great deal of debate but there's very little documentation or guidance on using NServiceBus with WebAPI or eve if it should be used at all.  I was hoping to catch Udi's webinar last night as I had asked the very question of NserviceBus and WebAPI but I missed a chunk of the webinar.

Thanks

Steve

Mauro Servienti

unread,
Dec 15, 2014, 4:32:36 AM12/15/14
to particula...@googlegroups.com
Hi Steve,

to me it is not clear what you are trying to achieve.
As far as I have understood you have a WebAPI call that will be forwarded to a message on a queue and in the same Action handler you are setting up a Callback on that Bus.Send.

You're goal is: if no reply is sent within "t" then send back a timeout http response code?

Steve Wilkinson

unread,
Dec 15, 2014, 5:31:00 AM12/15/14
to particula...@googlegroups.com
Hi Mauro,

Yes the goal is for a WebAPI call to send a command via the bus and register a callback to know when the handler has processed the command (i.e. Bus.Send(cmd).Register(.....).  The handler will use Bus.Return to return a status code back to the WebAPI.  If the handler doesn't respond within a set time then the WebAPI call will timeout and return an Http Timeout status code to the caller.

Apart from an example I'd really like to know the correct way NServiceBus and WebAPI should be used (i.e. the do's, don'ts etc.) as it seems to be a topic that just doesn't get discussed, the documentation is certainly very thin.

Thanks

Steve

Mauro Servienti

unread,
Dec 15, 2014, 6:14:55 AM12/15/14
to particula...@googlegroups.com
Hi Steve,

I’d say that callbacks cannot be used in a IIS / Web based scenario to achieve what you want, let me explain what issues you can face:

- give that messages are async as soon as you send the message and setup the callback the http request is gone and immediately returned to the caller, the only way I see to prevent it is to set up a mutex that lock the request thread until the callback is received or a timeout is reached; isn’t this lite trying to make something async sync?

- Since callbacks are handled in memory (http://docs.particular.net/nservicebus/how-do-i-handle-responses-on-the-client-side) what can happen is that while you are waiting the Application Pool is recycled and each callback is lost;

- In a scale-out scenario, using callbacks and competing consumers, the callback message can be received by a different machine other than the one that is waiting it;

I generally utilize WebAPI as a front end to the bus to allow JavaScript to post messages to the bus and then waiting for responses, where required, using WebSockets (SignalR in my case), or reverting to polling if SignalR is not supported or something goes wrong with the socket.

.m
--
(no keyboard keys have been killed due to the really annoying OSX spell checker)
--
You received this message because you are subscribed to the Google Groups "Particular Software" group.
To unsubscribe from this group and stop receiving emails from it, send an email to particularsoftw...@googlegroups.com.
To post to this group, send email to particula...@googlegroups.com.
Visit this group at http://groups.google.com/group/particularsoftware.
To view this discussion on the web visit https://groups.google.com/d/msgid/particularsoftware/f6394707-24ca-49c6-b1a4-c590b96ef092%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Steve Wilkinson

unread,
Dec 15, 2014, 8:08:54 AM12/15/14
to particula...@googlegroups.com
Hi Mauro,

We've played around with WebAPI sending something to the bus and registering a callback.  We had this working by marking the WebAPI and controller methods async and then used await to wait for the result of the callback.  What I wanted to know was how to handle a timeout where for some reason the handler never sent a response.  Yes I guess we are trying to make the asynchronous operation synchronous but is this not necessary sometimes for short lived UI operations ? After all WebAPI is request/response. In a traditional scenario without a bus the whole thing would be synchronous anyway unless you got funky with SignalR.

I guess I'm struggling to see how NServiceBus should work with WebAPI, perhaps the question should be "How should I build my UI to work with WebAPI and NServiceBus ?".

I fully get that the bus should not be used for querying data and it should in most cases issue commands in a sort of fire and forget fashion.  So what's the strategy for building the UI ?  Do you just make an assumption that most UI commands should complete in a short time and just assume that you UI will be eventually consistent ?  Or do you have to employ polling or SignalR for every type of UI operation both short and long running ?

I've never seen a decent sample application for NServiceBus hooked up to WebAPI, certainly there needs to be better guidance in the documentation.

Thanks

Steve

To unsubscribe from this group and stop receiving emails from it, send an email to particularsoftware+unsub...@googlegroups.com.
To post to this group, send email to particul...@googlegroups.com.

Mauro Servienti

unread,
Dec 15, 2014, 8:40:07 AM12/15/14
to particula...@googlegroups.com
We've played around with WebAPI sending something to the bus and registering a callback.  We had this working by marking the WebAPI and controller methods async and then used await to wait for the result of the callback.  What I wanted to know was how to handle a timeout where for some reason the handler never sent a response.

The only thing that comes to my mind is something like (not tested at all):

public Task<HttpStatusCode> ExecuteSomething() 

{

var task = this.Bus.Send( null )

.Register( r => 

{

                    //callback handling logic here

} );


var completed = task.Wait( 2000 );

if( !completed ) 

{

//timed out

return Task.FromResult( HttpStatusCode.RequestTimeout );

}


return Task.FromResult( HttpStatusCode.OK );

}


Yes I guess we are trying to make the asynchronous operation synchronous but is this not necessary sometimes for short lived UI operations ?

My guess is that the assumption “short lived” can be problematic, and really depends on so many factors that can be hard to determine that something is timing out after a set, and known upfront, amount of time.

I use to implement this timeout logic in the UI/front end that knows what is going on, handling a timeout at the UI level allows me to ask to the user what we should do next, e.g. wait some more time?, something that at the web server level cannot be done.

After all WebAPI is request/response. In a traditional scenario without a bus the whole thing would be synchronous anyway unless you got funky with SignalR.

I guess I'm struggling to see how NServiceBus should work with WebAPI, perhaps the question should be "How should I build my UI to work with WebAPI and NServiceBus ?".

I fully get that the bus should not be used for querying data and it should in most cases issue commands in a sort of fire and forget fashion.  So what's the strategy for building the UI ?  Do you just make an assumption that most UI commands should complete in a short time and just assume that you UI will be eventually consistent ?  Or do you have to employ polling or SignalR for every type of UI operation both short and long running ?

My assumption is that each command is always backed and followed by at least one event, the front-end is subscribed to all the events and will push these events to the UI via SignalR, what you need now is a way to correlate things back, since when pushing with SignalR what happens is that you are pushing every event to every client regardless that that client is waiting for that event, so a client needs to understand if a specific event is the one it is waiting for.

Given the above assumption the client needs to be able to generate unique Correlation IDs, or Conversation IDs, that will attach to every sent request that will generate a command and expects a reply back via an event.

I've never seen a decent sample application for NServiceBus hooked up to WebAPI, certainly there needs to be better guidance in the documentation.

That is far from easy, unfortunately, we are working in order to understand which is the best way to approach it, the issue is that in order to give a real world sample that handles a lot of the issues and the details that one can face in production the result is not a sample any more :-)

Reply all
Reply to author
Forward
0 new messages