如何在Undertow中执行非阻止处理程序中的阻止代码



,如一个单独的问题所述,当使用procestow时,所有处理都应在专用的工作线池中进行,看起来像这样:

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可用于明确讲述承诺,以安排专用线程池上的请求以阻止请求。我们可以通过在BlockingHandler的实例中包装HttpHandler来调整上述示例,就像:

        .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的说法,除非您确实需要使用输入流,否则此调用仍然是一个封锁。

调用此方法将交易所处于阻塞模式,并创建一个 阻止htttpexchange对象存储流。当交流是 在阻止模式下,输入流方法可用,除了 目前,阻止一个 非阻滞模式

如何将此阻止呼叫变成一个非阻止呼叫?

正确的方法是在IO线程中实际执行逻辑,如果它是非阻滞的。否则,将请求委派给了专用线程,例如:

public class Example {
  public static void main(String[] args) {
    Undertow server = Undertow.builder()
        .addListener(8080, "localhost")
        .setHandler(new HttpHandler() {
          public void handleRequest(HttpServerExchange exchange)
              throws Exception {
            if (valueIsPresentInCache(exchange)) {
              getValueFromCache();  // non-blocking, can be done from IO thread           
            } else {
              if (exchange.isInIoThread()) {
                exchange.dispatch(this);
                // we return immediately, otherwise this request will be
                // handled both in IO thread and a Worker thread, throwing
                // an exception
                return;
              }
              fetchValueFromDatabase(); // blocking!!!
            }
          }
        })
        .build();
    server.start();
  }
}

相关内容

  • 没有找到相关文章

最新更新