<div dir="ltr">Thanks for the clarification. I think I'm OK, but want to double check.<div><br></div><div>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.</div><div><br></div><div>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. </div><div><br></div><div>Does that all sound correct?</div></div><br><div class="gmail_quote"><div dir="ltr">On Tue, Nov 22, 2016 at 1:12 PM Stuart Douglas <<a href="mailto:sdouglas@redhat.com">sdouglas@redhat.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On Wed, Nov 23, 2016 at 7:56 AM, Oliver Dain <<a href="mailto:oliver@analyticspot.com" class="gmail_msg" target="_blank">oliver@analyticspot.com</a>> wrote:<br class="gmail_msg">
> Wow! Thanks for the super-fast reply.<br class="gmail_msg">
><br class="gmail_msg">
> I think I'm a little confused about the difference between being in an IO<br class="gmail_msg">
> thread and being dispatched. Is it the case that if the server thinks I'm<br class="gmail_msg">
> "not dispatched" (that is, if the server will send a response on my behalf<br class="gmail_msg">
> when my method returns) that I'm always on an IO thread? I often do some<br class="gmail_msg">
> work on my own thread pools and those threads often interact with the<br class="gmail_msg">
> HttpServerExchange object. I know that some interactions with the exchange<br class="gmail_msg">
> object (e.g. recieveFullBytes) will take an exchange that is in a dispatched<br class="gmail_msg">
> state and put it in a non-dispatched state. So I want to just keep checking<br class="gmail_msg">
> that I'm dispatched and, if I'm not, dispatch again. So my code might look<br class="gmail_msg">
> something like:<br class="gmail_msg">
><br class="gmail_msg">
> void handle(HttpServerExchange exchange) {<br class="gmail_msg">
> exchange.dispatch(myOwnThreadPoolExecutor, () -> {<br class="gmail_msg">
> <a href="http://log.info" rel="noreferrer" class="gmail_msg" target="_blank">log.info</a>("I am not not on an IO thread and I am dispatched.");<br class="gmail_msg">
> doSomethingWithExchange(exchange);<br class="gmail_msg">
> assert exchange.isDispatched();<br class="gmail_msg">
> assert !exchange.isInIoThread();<br class="gmail_msg">
> // how do I check to see if I'm still in a dispatched state?<br class="gmail_msg">
> });<br class="gmail_msg">
> }<br class="gmail_msg">
<br class="gmail_msg">
So the basic idea behind the 'dispatch' is that it is a way of<br class="gmail_msg">
guaranteeing thread safety without needing to synchronize the exchange<br class="gmail_msg">
object. Effectively it allows you to pass an exchange from one thread<br class="gmail_msg">
to another in a way that guarantees that the first thread is 'done'<br class="gmail_msg">
with the exchange before the second thread starts.<br class="gmail_msg">
<br class="gmail_msg">
><br class="gmail_msg">
> (note: the above is a bad, super-simplified example and in the actual code<br class="gmail_msg">
> there's a lot of asynchronous stuff happening that bounces the execution<br class="gmail_msg">
> from one thread pool to another).<br class="gmail_msg">
><br class="gmail_msg">
> The reason for all of this is that I have some edge cases which appear to be<br class="gmail_msg">
> race conditions in which I know for sure that I call exchange.dispatch() and<br class="gmail_msg">
> then I start doing some work but the exchange gets ended before I've<br class="gmail_msg">
> finished my computations and have a response to send leaving the client with<br class="gmail_msg">
> an empty response. I'm not entirely sure how that could happen, but my best<br class="gmail_msg">
> guess right now is that I interact with the exchange in some way that causes<br class="gmail_msg">
> it to no longer be in in the dispatched state and, as a result, the<br class="gmail_msg">
> HttpServerExchange is ending the exchange for me before I'm ready.<br class="gmail_msg">
<br class="gmail_msg">
I think I would need to look at a more specific example of what you<br class="gmail_msg">
are doing, but it is possibly related to how you are handing stuff in<br class="gmail_msg">
other threads? The exchange itself is not thread safe, if you start<br class="gmail_msg">
doing work on the exchange in another thread without having dispatched<br class="gmail_msg">
you can get a race condition.<br class="gmail_msg">
<br class="gmail_msg">
Stuart<br class="gmail_msg">
<br class="gmail_msg">
><br class="gmail_msg">
> Thanks again,<br class="gmail_msg">
> Oliver<br class="gmail_msg">
><br class="gmail_msg">
><br class="gmail_msg">
><br class="gmail_msg">
> On Tue, Nov 22, 2016 at 12:47 PM Stuart Douglas <<a href="mailto:sdouglas@redhat.com" class="gmail_msg" target="_blank">sdouglas@redhat.com</a>> wrote:<br class="gmail_msg">
>><br class="gmail_msg">
>> After the call stack returns and the dispatch actually happens<br class="gmail_msg">
>> isDispatched() will return false (allowing the exchange to be<br class="gmail_msg">
>> dispatched again).<br class="gmail_msg">
>><br class="gmail_msg">
>> In general you should not really need to check this anyway, if you<br class="gmail_msg">
>> want to know if you are in the IO thread you should use isInIiThread()<br class="gmail_msg">
>> instead.<br class="gmail_msg">
>><br class="gmail_msg">
>> Stuart<br class="gmail_msg">
>><br class="gmail_msg">
>> On Wed, Nov 23, 2016 at 7:44 AM, Oliver Dain <<a href="mailto:oliver@analyticspot.com" class="gmail_msg" target="_blank">oliver@analyticspot.com</a>><br class="gmail_msg">
>> wrote:<br class="gmail_msg">
>> > I've got some pretty simple code that looks something like:<br class="gmail_msg">
>> ><br class="gmail_msg">
>> > if (!exhange.isDispatched()) {<br class="gmail_msg">
>> > exchange.dispatch(() -> {<br class="gmail_msg">
>> > assert exchange.isDispatched();<br class="gmail_msg">
>> > // more stuff....<br class="gmail_msg">
>> > });<br class="gmail_msg">
>> > }<br class="gmail_msg">
>> ><br class="gmail_msg">
>> > but the assert fails. That is, when dispatch calls my runnable<br class="gmail_msg">
>> > isDispatched<br class="gmail_msg">
>> > is not true.<br class="gmail_msg">
>> ><br class="gmail_msg">
>> > I believe I have a bug somewhere with how/when dispatches are happening<br class="gmail_msg">
>> > so<br class="gmail_msg">
>> > I've littered my code with such asserts and they fail reliably even when<br class="gmail_msg">
>> > I'm<br class="gmail_msg">
>> > quite sure the exchange has been dispatched (e.g. when it is literally<br class="gmail_msg">
>> > the<br class="gmail_msg">
>> > first call in a Runnable passed to to the dispatch() method).<br class="gmail_msg">
>> ><br class="gmail_msg">
>> > What am I doing wrong?<br class="gmail_msg">
>> > --<br class="gmail_msg">
>> > CTO, Analytic Spot<br class="gmail_msg">
>> > 44 West Broadway #222<br class="gmail_msg">
>> > Eugene, OR 97401<br class="gmail_msg">
>> > <a href="http://analyticspot.com" rel="noreferrer" class="gmail_msg" target="_blank">analyticspot.com</a> • <a href="tel:(425)%20296-6556" value="+14252966556" class="gmail_msg" target="_blank">425-296-6556</a><br class="gmail_msg">
>> > <a href="http://www.linkedin.com/in/oliverdain" rel="noreferrer" class="gmail_msg" target="_blank">www.linkedin.com/in/oliverdain</a><br class="gmail_msg">
>> ><br class="gmail_msg">
>> > _______________________________________________<br class="gmail_msg">
>> > undertow-dev mailing list<br class="gmail_msg">
>> > <a href="mailto:undertow-dev@lists.jboss.org" class="gmail_msg" target="_blank">undertow-dev@lists.jboss.org</a><br class="gmail_msg">
>> > <a href="https://lists.jboss.org/mailman/listinfo/undertow-dev" rel="noreferrer" class="gmail_msg" target="_blank">https://lists.jboss.org/mailman/listinfo/undertow-dev</a><br class="gmail_msg">
><br class="gmail_msg">
> --<br class="gmail_msg">
> CTO, Analytic Spot<br class="gmail_msg">
> 44 West Broadway #222<br class="gmail_msg">
> Eugene, OR 97401<br class="gmail_msg">
> <a href="http://analyticspot.com" rel="noreferrer" class="gmail_msg" target="_blank">analyticspot.com</a> • <a href="tel:(425)%20296-6556" value="+14252966556" class="gmail_msg" target="_blank">425-296-6556</a><br class="gmail_msg">
> <a href="http://www.linkedin.com/in/oliverdain" rel="noreferrer" class="gmail_msg" target="_blank">www.linkedin.com/in/oliverdain</a><br class="gmail_msg">
</blockquote></div><div dir="ltr">-- <br></div><div data-smartmail="gmail_signature"><div dir="ltr"><div style="font-size:small"><div style="font-size:13px;line-height:19.5px">CTO, Analytic Spot</div><div style="font-size:13px;line-height:19.5px">44 West Broadway #222</div><div style="font-size:13px;line-height:19.5px">Eugene, OR 97401<br></div><div style="font-size:13px;line-height:19.5px"><a href="http://analyticspot.com/" style="z-index: 0;">analyticspot.com</a> <span style="color:rgb(127,127,127);font-family:'helvetica neue';font-size:11px;line-height:normal">• </span>425-296-6556</div></div><div style="font-size:small"><span style="line-height:19.5px"><a href="http://www.linkedin.com/in/oliverdain" style="z-index: 0;">www.linkedin.com/in/oliverdain</a></span></div></div></div>