This handler is implemented incorrectly because exchange will end right
after handleRequest method is called.
In order to fix this we can use dispatching (only implementation of
handleRequest method is shown):
public void handleRequest(final HttpServerExchange exchange) throws
Exception {
if (exchange.isInIoThread()) {
exchange.dispatch(new Runnable() {
public void run() {
new Timer().schedule(new TimerTask() {
public void run() {
Connectors.executeRootHandler(new
HttpHandler() {
public void
handleRequest(HttpServerExchange exchange) throws Exception {
exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "text/plain");
exchange.getResponseSender().send("Returned in 5 seconds");
}
}, exchange);
}
}, 5000);
}
});
}
}
Please pay attention that the requirement here is not to use dumb
blocking in the work thread (like Thread.sleep(5000)) but rely on
asynchronous event handling instead.
I would appreciate if someone can answer the following questions:
You don't need the isInIoThread() check, otherwise this handler will do
nothing if an earlier handler dispatched (e.g. a security handler that
needed to do a blocking LDAP lookup).
* Are there any pitfalls with the working
dispatch/executeRootHandler
solution mentioned above?
No, this is the correct way to do it. Undertow's exchange is not thread
safe (as making it thread safe seriously degrades performance by an
order of magnitude). Instead multi-threading is implemented by having a
safe hand off point (the dispatch() method), which basically allows a
thread to hand off to another thread when it is done, so only one thread
'owns' the exchange at a time.
You can just call the dispatch() method with no arguments to stop the
exchange ending, but if your async task finished before the call stack
returns then you will have two threads active in the exchange, which
will cause all kinds of potential problems (this is not going to happen
with a 5000ms delay, but with a 1ms delay it will).
* Is there a simpler and more elegant way to achieve the same?
I assume you are not actually dealing with timers and this was just an
example, but if you do want to schedule a task (like a timeout for
instance) you can schedule it using
exchange.getIoThread().executeAfter(), which will run the timed task in
the IO thread.
Stuart
--
Vladimir Tsukur
Software Architect, Design Engineer and Scrum Master
_______________________________________________
undertow-dev mailing list
undertow-dev(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/undertow-dev