Hi,

In order to read the content of the requests my HttpHandler use receivePartialBytes as follows:

public class AsyncReaderHttpHandler implements HttpHandler {

@Override
public void handleRequest(HttpServerExchange exchange) throws Exception {

if (exchange.isInIoThread()) {
exchange.dispatch(this);
return;
}

readRequest(exchange);
}

private void readRequest(HttpServerExchange exchange) {
exchange.getRequestReceiver().receivePartialBytes(new MyCallback());
}

public class MyCallback implements PartialBytesCallback {

@Override
public void handle(HttpServerExchange exchange, byte[] message, boolean last) {
if (exchange.isInIoThread()) {
exchange.dispatch(() -> handleData(exchange, message, last));
} else {
handleData(exchange, message, last);
}
}

private void handleData(HttpServerExchange exchange, byte[] message, boolean last) {
// do some blocking operation with the data
}
}
}
My handler dispatching to worker thread and than calls receivePartialBytes() with a callback.

At first, I thought that the handle() method of the callback will always be called from a worker thread context.
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.

After adding the second call to dispatch() my code started to fail with:

java.lang.IllegalStateException: UT000146: HttpServerExchange cannot have both async IO resumed and dispatch() called in the same cycle
at io.undertow.server.HttpServerExchange$ReadDispatchChannel.resumeReads(HttpServerExchange.java:2100)
at io.undertow.io.AsyncReceiverImpl$5$2.handleRequest(AsyncReceiverImpl.java:554)
at io.undertow.server.Connectors.executeRootHandler(Connectors.java:332)
at io.undertow.io.AsyncReceiverImpl$5.handleEvent(AsyncReceiverImpl.java:549)
at io.undertow.io.AsyncReceiverImpl$5.handleEvent(AsyncReceiverImpl.java:516)
at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
at io.undertow.channels.DetachableStreamSourceChannel$SetterDelegatingListener.handleEvent(DetachableStreamSourceChannel.java:231)
at io.undertow.channels.DetachableStreamSourceChannel$SetterDelegatingListener.handleEvent(DetachableStreamSourceChannel.java:218)
at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
at org.xnio.conduits.ReadReadyHandler$ChannelListenerHandler.readReady(ReadReadyHandler.java:66)
at org.xnio.nio.NioSocketConduit.handleReady(NioSocketConduit.java:88)
at org.xnio.nio.WorkerThread.run(WorkerThread.java:561)


What am I missing here? how can I use the asynchronous receiver and not risking in blocking I/O thread?

I'm using Undertow 1.4.19.Final.

Thanks!