[undertow-dev] dispatch and isDispatched do not agree

Oliver Dain oliver at analyticspot.com
Tue Nov 22 17:45:42 EST 2016


Got it. Thanks!!

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

> That all sounds pretty much correct.
>
> One thing to be aware of is that there is a difference between
> dispatch(Runnable) and dispatch(HttpHandler), in that the HttpHandler
> one will end the exchange when the call stack returns (unless it was
> dispatched again). It sounds like the variant you want is the Runnable
> one.
>
> Stuart
>
> On Wed, Nov 23, 2016 at 8:20 AM, Oliver Dain <oliver at analyticspot.com>
> wrote:
> > 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
> >> >> > 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
> >> > 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
>
-- 
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/9d577251/attachment-0001.html 


More information about the undertow-dev mailing list