[undertow-dev] dispatching from AsyncReceiverImpl.receivePartialBytes callback fails

Eldad Rudich eldadru at gmail.com
Wed Mar 28 13:17:26 EDT 2018


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!
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/undertow-dev/attachments/20180328/ba4547e4/attachment-0001.html 


More information about the undertow-dev mailing list