<div dir="ltr"><div>Imagine the use case when sending response does not happen from IO or worker thread, but instead originates as a part of asynchronous event handling in an application thread.<br></div><div><br></div><div>
Below is a code snippet for a simple timer use case where response is meant to be sent in 5 seconds after receiving a request. This solution is put here just to illustrate the point, it does NOT work for the obvious reason that we'll cover later:</div>
<div><br></div><div><div><div> final Undertow undertow = Undertow.builder()</div><div> .addHttpListener(9090, "localhost")</div><div> .setHandler(new HttpHandler() {</div><div> public void handleRequest(final HttpServerExchange exchange) throws Exception {<br>
</div><div> new Timer().schedule(new TimerTask() {</div><div> public void run() {<br></div><div> exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "text/plain");</div>
<div> exchange.getResponseSender().send("Returned in 5 seconds");</div><div> }</div><div> }, 5000);</div><div> }</div><div> }).build();</div>
<div> undertow.start();</div></div><div><br></div><div>This handler is implemented incorrectly because exchange will end right after handleRequest method is called.</div><div><br></div><div>In order to fix this we can use dispatching (only implementation of handleRequest method is shown):</div>
<div><br></div><div><div> public void handleRequest(final HttpServerExchange exchange) throws Exception {</div><div> if (exchange.isInIoThread()) {</div><div> exchange.dispatch(new Runnable() {</div><div>
public void run() {<br></div><div> new Timer().schedule(new TimerTask() {</div><div> public void run() {<br></div><div> Connectors.executeRootHandler(new HttpHandler() {</div>
<div> public void handleRequest(HttpServerExchange exchange) throws Exception {<br></div><div> exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "text/plain");</div>
<div> exchange.getResponseSender().send("Returned in 5 seconds");</div><div> }</div><div> }, exchange);</div><div> }</div>
<div> }, 5000);</div><div> }</div><div> });</div><div> }</div><div> }</div></div><div><br></div><div>Please pay attention that the requirement here is not to use dumb blocking in the work thread (like Thread.sleep(5000)) but rely on asynchronous event handling instead.</div>
<div><br></div><div>I would appreciate if someone can answer the following questions:</div><div><ul><li>Are there any pitfalls with the working dispatch/executeRootHandler solution mentioned above?</li><li>Is there a simpler and more elegant way to achieve the same?</li>
</ul></div>-- <br>Vladimir Tsukur<br>Software Architect, Design Engineer and Scrum Master
</div></div>