<div dir="ltr">Hi,<div><br></div><div>In order to read the content of the requests my HttpHandler use receivePartialBytes as follows:</div><div><br></div><div><pre style="background-color:rgb(43,43,43);color:rgb(169,183,198);font-family:Consolas;font-size:12pt"><span style="color:rgb(204,120,50)">public class </span>AsyncReaderHttpHandler <span style="color:rgb(204,120,50)">implements </span>HttpHandler {<br><br>  <span style="color:rgb(187,181,41)">@Override<br></span><span style="color:rgb(187,181,41)">  </span><span style="color:rgb(204,120,50)">public void </span><span style="color:rgb(255,198,109)">handleRequest</span>(HttpServerExchange exchange) <span style="color:rgb(204,120,50)">throws </span>Exception {<br><br>    <span style="color:rgb(204,120,50)">if </span>(exchange.isInIoThread()) {<br>      exchange.dispatch(<span style="color:rgb(204,120,50)">this</span>)<span style="color:rgb(204,120,50)">;<br></span><span style="color:rgb(204,120,50)">      return;<br></span><span style="color:rgb(204,120,50)">    </span>}<br><br>    readRequest(exchange)<span style="color:rgb(204,120,50)">;<br></span><span style="color:rgb(204,120,50)">  </span>}<br><br>  <span style="color:rgb(204,120,50)">private void </span><span style="color:rgb(255,198,109)">readRequest</span>(HttpServerExchange exchange) {<br>    exchange.getRequestReceiver().receivePartialBytes(<span style="color:rgb(204,120,50)">new </span>MyCallback())<span style="color:rgb(204,120,50)">;<br></span><span style="color:rgb(204,120,50)">  </span>}<br><br>  <span style="color:rgb(204,120,50)">public class </span>MyCallback <span style="color:rgb(204,120,50)">implements </span>PartialBytesCallback {<br><br>    <span style="color:rgb(187,181,41)">@Override<br></span><span style="color:rgb(187,181,41)">    </span><span style="color:rgb(204,120,50)">public void </span><span style="color:rgb(255,198,109)">handle</span>(HttpServerExchange exchange<span style="color:rgb(204,120,50)">, byte</span>[] message<span style="color:rgb(204,120,50)">, boolean </span>last) {<br>      <span style="color:rgb(204,120,50)">if </span>(exchange.isInIoThread()) {<br>        exchange.dispatch(() -&gt; handleData(<span style="color:rgb(179,137,197)">exchange</span><span style="color:rgb(204,120,50)">, </span><span style="color:rgb(179,137,197)">message</span><span style="color:rgb(204,120,50)">, </span><span style="color:rgb(179,137,197)">last</span>))<span style="color:rgb(204,120,50)">;<br></span><span style="color:rgb(204,120,50)">      </span>} <span style="color:rgb(204,120,50)">else </span>{<br>        handleData(exchange<span style="color:rgb(204,120,50)">, </span>message<span style="color:rgb(204,120,50)">, </span>last)<span style="color:rgb(204,120,50)">;<br></span><span style="color:rgb(204,120,50)">      </span>}<br>    }<br><br>    <span style="color:rgb(204,120,50)">private void </span><span style="color:rgb(255,198,109)">handleData</span>(HttpServerExchange exchange<span style="color:rgb(204,120,50)">, byte</span>[] message<span style="color:rgb(204,120,50)">, boolean </span>last) {<br>      <span style="color:rgb(7,128,11)">// do some blocking operation with the data<br></span><span style="color:rgb(7,128,11)">    </span>}<br>  }<br>}</pre>My handler dispatching to worker thread and than calls receivePartialBytes() with a callback.</div><div><br></div><div>At first, I thought that the handle() method of the callback will always be called from a worker thread context.</div><div>I was surprised to discover that in some cases the callback will be called from I/O thread (why?), so I had to add the second call to dispatch() inside the callback.</div><div><br></div><div>After adding the second call to dispatch() my code started to fail with:</div><div><br></div><div><div>java.lang.IllegalStateException: UT000146: HttpServerExchange cannot have both async IO resumed and dispatch() called in the same cycle</div><div><span style="white-space:pre">        </span>at io.undertow.server.HttpServerExchange$ReadDispatchChannel.resumeReads(HttpServerExchange.java:2100)</div><div><span style="white-space:pre">        </span>at io.undertow.io.AsyncReceiverImpl$5$2.handleRequest(AsyncReceiverImpl.java:554)</div><div><span style="white-space:pre">        </span>at io.undertow.server.Connectors.executeRootHandler(Connectors.java:332)</div><div><span style="white-space:pre">        </span>at io.undertow.io.AsyncReceiverImpl$5.handleEvent(AsyncReceiverImpl.java:549)</div><div><span style="white-space:pre">        </span>at io.undertow.io.AsyncReceiverImpl$5.handleEvent(AsyncReceiverImpl.java:516)</div><div><span style="white-space:pre">        </span>at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)</div><div><span style="white-space:pre">        </span>at io.undertow.channels.DetachableStreamSourceChannel$SetterDelegatingListener.handleEvent(DetachableStreamSourceChannel.java:231)</div><div><span style="white-space:pre">        </span>at io.undertow.channels.DetachableStreamSourceChannel$SetterDelegatingListener.handleEvent(DetachableStreamSourceChannel.java:218)</div><div><span style="white-space:pre">        </span>at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)</div><div><span style="white-space:pre">        </span>at org.xnio.conduits.ReadReadyHandler$ChannelListenerHandler.readReady(ReadReadyHandler.java:66)</div><div><span style="white-space:pre">        </span>at org.xnio.nio.NioSocketConduit.handleReady(NioSocketConduit.java:88)</div><div><span style="white-space:pre">        </span>at org.xnio.nio.WorkerThread.run(WorkerThread.java:561)</div></div><div><br></div><div><br></div><div>What am I missing here? how can I use the asynchronous receiver and not risking in blocking I/O thread?</div><div><br></div><div>I&#39;m using Undertow 1.4.19.Final.</div><div><br></div><div>Thanks!</div></div>