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

Stuart Douglas sdouglas at redhat.com
Wed Mar 28 18:25:07 EDT 2018


You need to call io.undertow.io.Receiver#pause() to pause the IO. This is
so that you don't end up with multiple threads working on the exchange. If
you don't want to pause (i.e. you hare happy to have more data keep coming
and being processed while your blocking task is running) then you do this
by just directly submitting the task to the worker, and not calling
dispatch.

This exists to keep Undertow's operation effectively single threaded, even
though the exchange moves between threads one thread is always complete
before the next one starts. If you do go with the second option of
submitting to the worker you will need to come up with your own way of
enforcing 'only one thread using the exchange'.

Stuart



On Thu, Mar 29, 2018 at 4:17 AM, Eldad Rudich <eldadru at gmail.com> wrote:

> 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!
>
> _______________________________________________
> undertow-dev mailing list
> undertow-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/undertow-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/undertow-dev/attachments/20180329/2a0b0932/attachment.html 


More information about the undertow-dev mailing list