Correctly shutting down a websocket handler
by Robin Anil
When a client disconnects, I see that onClose is not being fired. The only
way this seems to be firing if client sents a close frame.
Is there any way to detect disconnection and immediately close all the
opened resources.
Robin
Robin Anil | Software Engineer
1 year
dispatching from AsyncReceiverImpl.receivePartialBytes callback fails
by Eldad Rudich
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!
6 years, 6 months
Inconsistency in performing async task
by Nabeel Imtiaz
Hi,
I'm trying to perform expensive tasks (like sending email/sms etc) as an
async task (using CompletableFuture API) after my undertow worker completes
and i'm about to respond to the client. These tasks are supposed to work
like fire and forget and I don't want to wait until the task completes and
then respond to the client.
I've noticed that sometimes the task doesn't execute and sometimes it does.
It's inconsistent and hard to reproduce. Is there a way to be able to
perform these async tasks consistently? May be i'm using wrong thread-pool?
Or may be there's already a way in Undertow to do such tasks.
Please comment.
Thanks.
6 years, 6 months
Question about endExchange() and response Sender
by Mario Carbajal
In a dispatched non-blocking HttpRequest handler I'm calling endExchange
immediately after calling send on the response Sender. I am unsure if this
will cause the sender to be interrupted or if the exchange will end only
after the sender is done writing the data.
The code looks like this:
@Override
public void handleRequest(HttpServerExchange exchange) throws Exception
{
if (exchange.isInIoThread()) {
exchange.dispatch(this);
return;
}
try {
... do things ...
exchange.getResponseSender().send(data);
}finally {
exchange.endExchange();
}
}
6 years, 6 months