Как описано в отдельном вопросе , при использовании Undertow вся обработка должна выполняться в выделенном пуле рабочих потоков, который выглядит следующим образом:
public class Start {
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();
}
}
Я понимаю, что BlockingHandler
можно использовать для явного указания Undertow планировать запрос в выделенном пуле потоков для блокировки запросов. Мы могли бы адаптировать приведенный выше пример, заключив HttpHandler
в экземпляр BlockingHandler
, например:
.setHandler(new BlockingHandler(new HttpHandler() {
Это будет работать для вызовов, которые, как мы знаем, всегда блокируют.
Однако, если какой-то код неблокирует большую часть времени, но иногда требуется блокирующий вызов, как превратить этот блокирующий вызов в неблокирующий? Например, если запрошенное значение присутствует в кеше, следующий код не будет блокироваться (это просто выборка из некоторого Map<>
), но если это не так, его нужно извлечь из базы данных.
public class Start {
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;
}
if (valueIsPresentInCache(exchange)) {
return valueFromCache; // non-blocking
} else {
return fetchValueFromDatabase(); // blocking!!!
}
}
})
.build();
server.start();
}
}
Согласно документам , существует метод HttpServerExchange.startBlocking()
, но согласно JavaDoc, если вам действительно не нужно использовать входной поток, этот вызов все еще является блокирующим.
Вызов этого метода переводит обмен в режим блокировки и создает
BlockingHttpExchange объект для хранения потоков. Когда обмен
в режиме блокировки становятся доступными методы входного потока, кроме
что в настоящее время нет большой разницы между блокированием
неблокирующие режимы
Как превратить этот блокирующий вызов в неблокирующий?