Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Undertow how to do Non-blocking IO?

Tags:

java

undertow

I am using Undertow to create a simple application.

public class App {
    public static void main(String[] args) {
        Undertow server = Undertow.builder().addListener(8080, "localhost")
                .setHandler(new HttpHandler() {

                    public void handleRequest(HttpServerExchange exchange) throws Exception {
                        Thread.sleep(5000);
                        exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "text/plain");
                        exchange.getResponseSender().send("Hello World");
                    }

                }).build();
        server.start();
    }
}

I open a browser tab on localhost:8080 and I open a second tab also on localhost:8080

This time the first tab will wait 5 seconds, and the second will wait 10 seconds

Why is it so?

like image 232
eclipse Avatar asked Feb 28 '14 10:02

eclipse


1 Answers

The HttpHandler is executing in an I/O thread. As noted in the documentation:

IO threads perform non blocking tasks, and should never perform blocking operations because they are responsible for multiple connections, so while the operation is blocking other connections will essentially hang. One IO thread per CPU core is a reasonable default.

The request lifecycle docs discuss how to dispatch a request to a worker thread:

import io.undertow.Undertow;
import io.undertow.server.*;
import io.undertow.util.Headers;

public class Under {
  public static void main(String[] args) {
    Undertow server = Undertow.builder()
        .addListener(8080, "localhost")
        .setHandler(new HttpHandler() {
          public void handleRequest(HttpServerExchange exchange)
              throws Exception {
            if (exchange.isInIoThread()) {
              exchange.dispatch(this);
              return;
            }
            exchange.getResponseHeaders()
                    .put(Headers.CONTENT_TYPE, "text/plain");
            exchange.getResponseSender()
                    .send("Hello World");
          }
        })
        .build();
    server.start();
  }
}

I noted that you won't necessarily get one worker thread per request - when I set a breakpoint on the header put I got about one thread per client. There are gaps in both the Undertow and the underlying XNIO docs so I'm not sure what the intention is.

like image 104
McDowell Avatar answered Oct 13 '22 00:10

McDowell