<div dir="ltr"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span style="font-family:arial,sans-serif;font-size:13px">You don't need the isInIoThread() check, otherwise this handler will do nothing if an earlier handler dispatched (e.g. a security handler that needed to do a blocking LDAP lookup).</span></blockquote>
<div><br></div><div>That is true, thanks for pointing it out.</div><div class="gmail_extra"><span style="font-family:arial,sans-serif;font-size:13px"><br></span></div><div class="gmail_extra"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<span style="font-family:arial,sans-serif;font-size:13px">I assume you are not actually dealing with timers and this was just an example</span></blockquote><br>Yes, timer was just an example. I am dealing with asynchronous client API that is used from the handler.</div>
<div class="gmail_extra"><br></div><div class="gmail_extra">Thanks a lot for the answer!</div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Aug 18, 2014 at 2:42 AM, Stuart Douglas <span dir="ltr"><<a href="mailto:sdouglas@redhat.com" target="_blank">sdouglas@redhat.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div class=""><br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<br>
This handler is implemented incorrectly because exchange will end right<br>
after handleRequest method is called.<br>
<br>
In order to fix this we can use dispatching (only implementation of<br>
handleRequest method is shown):<br>
<br>
public void handleRequest(final HttpServerExchange exchange) throws<br>
Exception {<br>
if (exchange.isInIoThread()) {<br>
exchange.dispatch(new Runnable() {<br>
public void run() {<br>
new Timer().schedule(new TimerTask() {<br>
public void run() {<br>
Connectors.executeRootHandler(<u></u>new<br>
HttpHandler() {<br>
public void<br>
handleRequest(<u></u>HttpServerExchange exchange) throws Exception {<br>
<br>
exchange.getResponseHeaders().<u></u>put(Headers.CONTENT_TYPE, "text/plain");<br>
<br>
exchange.getResponseSender().<u></u>send("Returned in 5 seconds");<br>
}<br>
}, exchange);<br>
}<br>
}, 5000);<br>
}<br>
});<br>
}<br>
}<br>
<br>
Please pay attention that the requirement here is not to use dumb<br>
blocking in the work thread (like Thread.sleep(5000)) but rely on<br>
asynchronous event handling instead.<br>
<br>
I would appreciate if someone can answer the following questions:<br>
<br>
</blockquote>
<br></div>
You don't need the isInIoThread() check, otherwise this handler will do nothing if an earlier handler dispatched (e.g. a security handler that needed to do a blocking LDAP lookup).<br>
<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
* Are there any pitfalls with the working dispatch/executeRootHandler<br>
solution mentioned above?<br>
</blockquote>
<br>
No, this is the correct way to do it. Undertow's exchange is not thread safe (as making it thread safe seriously degrades performance by an order of magnitude). Instead multi-threading is implemented by having a safe hand off point (the dispatch() method), which basically allows a thread to hand off to another thread when it is done, so only one thread 'owns' the exchange at a time.<br>
<br>
You can just call the dispatch() method with no arguments to stop the exchange ending, but if your async task finished before the call stack returns then you will have two threads active in the exchange, which will cause all kinds of potential problems (this is not going to happen with a 5000ms delay, but with a 1ms delay it will).<br>
<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
* Is there a simpler and more elegant way to achieve the same?<br>
</blockquote>
<br>
I assume you are not actually dealing with timers and this was just an example, but if you do want to schedule a task (like a timeout for instance) you can schedule it using<br>
<br>
exchange.getIoThread().<u></u>executeAfter(), which will run the timed task in the IO thread.<br>
<br>
Stuart<br>
<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div class="">
<br>
--<br>
Vladimir Tsukur<br>
Software Architect, Design Engineer and Scrum Master<br>
<br></div>
______________________________<u></u>_________________<br>
undertow-dev mailing list<br>
<a href="mailto:undertow-dev@lists.jboss.org" target="_blank">undertow-dev@lists.jboss.org</a><br>
<a href="https://lists.jboss.org/mailman/listinfo/undertow-dev" target="_blank">https://lists.jboss.org/<u></u>mailman/listinfo/undertow-dev</a><br>
</blockquote>
</blockquote></div><br><br clear="all"><div><br></div>-- <br>Vladimir Tsukur<br>Software Architect, Design Engineer and Scrum Master
</div></div>