[undertow-dev] dispatch and isDispatched do not agree

Oliver Dain oliver at analyticspot.com
Tue Nov 22 16:20:52 EST 2016


Thanks for the clarification. I think I'm OK, but want to double check.

I have some code that will pass an exchange object between thread pools not
owned by Undertow. I can guarantee that I won't interact with the exchange
from more than one thread at at time, but I will move it from thread pool
to thread pool. For example, I might get a request and call dispatch. I'd
then call a function that extracts a header from the exchange and then does
an async lookup in a database for the info that was found in the header.
When the DB lookup is complete I'll get a callback in a thread owned by the
DB. In that callback I might extract another header from the exchange and
then do another async lookup in a different database with a different
thread pool. When that call is complete I'll get a callback in yet another
thread, again not owned by Undertow. In that final callback I'd call
"exchange.getResponseSender().send(...)" to send the final response.

If I guarantee that I'm not operating on the exchange in more than one
thread at a time I shouldn't have to worry about synchronization. However,
since some async HttpServerExchange operations, like receiveFullBytes, can
put me back on the Undertow IO pool I do need to check
"exchange.isInIoThread()" and, if that returns true, I then need to call
dispatch again.

Does that all sound correct?

On Tue, Nov 22, 2016 at 1:12 PM Stuart Douglas <sdouglas at redhat.com> wrote:

> On Wed, Nov 23, 2016 at 7:56 AM, Oliver Dain <oliver at analyticspot.com>
> wrote:
> > Wow! Thanks for the super-fast reply.
> >
> > I think I'm a little confused about the difference between being in an IO
> > thread and being dispatched. Is it the case that if the server thinks I'm
> > "not dispatched" (that is, if the server will send a response on my
> behalf
> > when my method returns) that I'm always on an IO thread? I often do some
> > work on my own thread pools and those threads often interact with the
> > HttpServerExchange object. I know that some interactions with the
> exchange
> > object (e.g. recieveFullBytes) will take an exchange that is in a
> dispatched
> > state and put it in a non-dispatched state. So I want to just keep
> checking
> > that I'm dispatched and, if I'm not, dispatch again. So my code might
> look
> > something like:
> >
> > void handle(HttpServerExchange exchange) {
> >     exchange.dispatch(myOwnThreadPoolExecutor, () -> {
> >         log.info("I am not not on an IO thread and I am dispatched.");
> >         doSomethingWithExchange(exchange);
> >         assert exchange.isDispatched();
> >         assert !exchange.isInIoThread();
> >         // how do I check to see if I'm still in a dispatched state?
> >     });
> > }
>
> So the basic idea behind the 'dispatch' is that it is a way of
> guaranteeing thread safety without needing to synchronize the exchange
> object. Effectively it allows you to pass an exchange from one thread
> to another in a way that guarantees that the first thread is 'done'
> with the exchange before the second thread starts.
>
> >
> > (note: the above is a bad, super-simplified example and in the actual
> code
> > there's a lot of asynchronous stuff happening that bounces the execution
> > from one thread pool to another).
> >
> > The reason for all of this is that I have some edge cases which appear
> to be
> > race conditions in which I know for sure that I call exchange.dispatch()
> and
> > then I start doing some work but the exchange gets ended before I've
> > finished my computations and have a response to send leaving the client
> with
> > an empty response. I'm not entirely sure how that could happen, but my
> best
> > guess right now is that I interact with the exchange in some way that
> causes
> > it to no longer be in in the dispatched state and, as a result, the
> > HttpServerExchange is ending the exchange for me before I'm ready.
>
> I think I would need to look at a more specific example of what you
> are doing, but it is possibly related to how you are handing stuff in
> other threads? The exchange itself is not thread safe, if you start
> doing work on the exchange in another thread without having dispatched
> you can get a race condition.
>
> Stuart
>
> >
> > Thanks again,
> > Oliver
> >
> >
> >
> > On Tue, Nov 22, 2016 at 12:47 PM Stuart Douglas <sdouglas at redhat.com>
> wrote:
> >>
> >> After the call stack returns and the dispatch actually happens
> >> isDispatched() will return false (allowing the exchange to be
> >> dispatched again).
> >>
> >> In general you should not really need to check this anyway, if you
> >> want to know if you are in the IO thread you should use isInIiThread()
> >> instead.
> >>
> >> Stuart
> >>
> >> On Wed, Nov 23, 2016 at 7:44 AM, Oliver Dain <oliver at analyticspot.com>
> >> wrote:
> >> > I've got some pretty simple code that looks something like:
> >> >
> >> > if (!exhange.isDispatched()) {
> >> >     exchange.dispatch(() -> {
> >> >         assert exchange.isDispatched();
> >> >          // more stuff....
> >> >     });
> >> > }
> >> >
> >> > but the assert fails. That is, when dispatch calls my runnable
> >> > isDispatched
> >> > is not true.
> >> >
> >> > I believe I have a bug somewhere with how/when dispatches are
> happening
> >> > so
> >> > I've littered my code with such asserts and they fail reliably even
> when
> >> > I'm
> >> > quite sure the exchange has been dispatched (e.g. when it is literally
> >> > the
> >> > first call in a Runnable passed to to the dispatch() method).
> >> >
> >> > What am I doing wrong?
> >> > --
> >> > CTO, Analytic Spot
> >> > 44 West Broadway #222
> >> > Eugene, OR 97401
> >> > analyticspot.com • 425-296-6556 <(425)%20296-6556>
> >> > www.linkedin.com/in/oliverdain
> >> >
> >> > _______________________________________________
> >> > undertow-dev mailing list
> >> > undertow-dev at lists.jboss.org
> >> > https://lists.jboss.org/mailman/listinfo/undertow-dev
> >
> > --
> > CTO, Analytic Spot
> > 44 West Broadway #222
> > Eugene, OR 97401
> > analyticspot.com • 425-296-6556 <(425)%20296-6556>
> > www.linkedin.com/in/oliverdain
>
-- 
CTO, Analytic Spot
44 West Broadway #222
Eugene, OR 97401
analyticspot.com • 425-296-6556
www.linkedin.com/in/oliverdain
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/undertow-dev/attachments/20161122/e5dc44f7/attachment-0001.html 


More information about the undertow-dev mailing list