<p dir="ltr">Got it. Thanks!!</p>
<br><div class="gmail_quote"><div dir="ltr">On Tue, Nov 22, 2016, 2:02 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">That all sounds pretty much correct.<br class="gmail_msg">
<br class="gmail_msg">
One thing to be aware of is that there is a difference between<br class="gmail_msg">
dispatch(Runnable) and dispatch(HttpHandler), in that the HttpHandler<br class="gmail_msg">
one will end the exchange when the call stack returns (unless it was<br class="gmail_msg">
dispatched again). It sounds like the variant you want is the Runnable<br class="gmail_msg">
one.<br class="gmail_msg">
<br class="gmail_msg">
Stuart<br class="gmail_msg">
<br class="gmail_msg">
On Wed, Nov 23, 2016 at 8:20 AM, Oliver Dain <<a href="mailto:oliver@analyticspot.com" class="gmail_msg" target="_blank">oliver@analyticspot.com</a>> wrote:<br class="gmail_msg">
> Thanks for the clarification. I think I'm OK, but want to double check.<br class="gmail_msg">
><br class="gmail_msg">
> I have some code that will pass an exchange object between thread pools not<br class="gmail_msg">
> owned by Undertow. I can guarantee that I won't interact with the exchange<br class="gmail_msg">
> from more than one thread at at time, but I will move it from thread pool to<br class="gmail_msg">
> thread pool. For example, I might get a request and call dispatch. I'd then<br class="gmail_msg">
> call a function that extracts a header from the exchange and then does an<br class="gmail_msg">
> async lookup in a database for the info that was found in the header. When<br class="gmail_msg">
> the DB lookup is complete I'll get a callback in a thread owned by the DB.<br class="gmail_msg">
> In that callback I might extract another header from the exchange and then<br class="gmail_msg">
> do another async lookup in a different database with a different thread<br class="gmail_msg">
> pool. When that call is complete I'll get a callback in yet another thread,<br class="gmail_msg">
> again not owned by Undertow. In that final callback I'd call<br class="gmail_msg">
> "exchange.getResponseSender().send(...)" to send the final response.<br class="gmail_msg">
><br class="gmail_msg">
> If I guarantee that I'm not operating on the exchange in more than one<br class="gmail_msg">
> thread at a time I shouldn't have to worry about synchronization. However,<br class="gmail_msg">
> since some async HttpServerExchange operations, like receiveFullBytes, can<br class="gmail_msg">
> put me back on the Undertow IO pool I do need to check<br class="gmail_msg">
> "exchange.isInIoThread()" and, if that returns true, I then need to call<br class="gmail_msg">
> dispatch again.<br class="gmail_msg">
><br class="gmail_msg">
> Does that all sound correct?<br class="gmail_msg">
><br class="gmail_msg">
> On Tue, Nov 22, 2016 at 1:12 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">
>> 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>><br class="gmail_msg">
>> 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<br class="gmail_msg">
>> > IO<br class="gmail_msg">
>> > thread and being dispatched. Is it the case that if the server thinks<br class="gmail_msg">
>> > I'm<br class="gmail_msg">
>> > "not dispatched" (that is, if the server will send a response on my<br class="gmail_msg">
>> > 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<br class="gmail_msg">
>> > exchange<br class="gmail_msg">
>> > object (e.g. recieveFullBytes) will take an exchange that is in a<br class="gmail_msg">
>> > dispatched<br class="gmail_msg">
>> > state and put it in a non-dispatched state. So I want to just keep<br class="gmail_msg">
>> > checking<br class="gmail_msg">
>> > that I'm dispatched and, if I'm not, dispatch again. So my code might<br class="gmail_msg">
>> > 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<br class="gmail_msg">
>> > 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<br class="gmail_msg">
>> > to be<br class="gmail_msg">
>> > race conditions in which I know for sure that I call exchange.dispatch()<br class="gmail_msg">
>> > 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<br class="gmail_msg">
>> > with<br class="gmail_msg">
>> > an empty response. I'm not entirely sure how that could happen, but my<br class="gmail_msg">
>> > best<br class="gmail_msg">
>> > guess right now is that I interact with the exchange in some way that<br class="gmail_msg">
>> > 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>><br class="gmail_msg">
>> > 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<br class="gmail_msg">
>> >> > happening<br class="gmail_msg">
>> >> > so<br class="gmail_msg">
>> >> > I've littered my code with such asserts and they fail reliably even<br class="gmail_msg">
>> >> > when<br class="gmail_msg">
>> >> > I'm<br class="gmail_msg">
>> >> > quite sure the exchange has been dispatched (e.g. when it is<br class="gmail_msg">
>> >> > 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> • 425-296-6556<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> • 425-296-6556<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">
> 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> • 425-296-6556<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>