Обработчики откатов делают весь стек неблокирующим - PullRequest
0 голосов
/ 11 января 2019

Я изучаю undertow, потому что я видел, что это хороший выбор, если вы хотите реализовать неблокирующий ввод-вывод и хотите иметь реактивный прослушиватель http.

Undertow использует обработчики для обработки http-запросов неблокирующим способом.

Если у меня есть какая-то логика, которая должна быть реализована между запросом и ответом, как сделать эту логику тоже неблокируемой внутри обработчика откатов?

Я имею в виду, если он вставлен (или вызван) в метод handleRequest () уже отправлен в рабочий поток и , то уже неблокирует или вам нужно использовать CompletableFuture или Rx Observable или любую другую реактивную библиотеку, чтобы гарантировать, что весь стек является реактивным?

Это мой класс Handler в качестве заголовка примера, я имитирую читать Json, который будет проанализирован в объекте Person.class и преобразован (бизнес-логика), а затем возвращен обратно как ответ Json.

Я написал две альтернативы, чтобы лучше понять, как сделать весь стек реагирующим и неблокирующим. Какой из них мне нужно использовать?

public class DoBusinessLogicHandler  implements HttpHandler {

  JsonConverter json = JsonConverter.getInstance();

  @Override
  public void handleRequest(HttpServerExchange exchange) throws Exception {
    if (exchange.isInIoThread()) {
        exchange.dispatch(this);
        return;
    }

    Pooled<ByteBuffer> pooledByteBuffer = exchange.getConnection().getBufferPool().allocate();
    ByteBuffer byteBuffer = pooledByteBuffer.getResource();
    byteBuffer.clear();
    exchange.getRequestChannel().read(byteBuffer);
    int pos = byteBuffer.position();
    byteBuffer.rewind();
    byte[] bytes = new byte[pos];
    byteBuffer.get(bytes);
    byteBuffer.clear();
    pooledByteBuffer.free();

    String requestBody = new String(bytes, Charset.forName("UTF-8") );

    /* FIRST ALTERNATIVE:
    you can call the business logic directly because the whole body of handleRequest() is managed reactively
     */
    Person person = (Person) json.getObjectFromJson(requestBody, Person.class);
    Person p = transform(person);
    sendResponse(exchange, json.getJsonOf(p));


    /* SECOND ALTERNATIVE
    you must wrap business logic within a reactive construction (RxJava, CompletableFuture, ecc.) in order to
    have all the stack reactive
     */
    CompletableFuture
            .supplyAsync(()-> (Person) json.getObjectFromJson(requestBody, Person.class))
            .thenApply(p -> transform(p))
            .thenAccept(p -> sendResponse(exchange, json.getJsonOf(p)));

  }

  /* it could be also a database fetch or whatever */
  private Person transform(Person p){
    if(p!=null){
        p.setTitle(p.getTitle().toUpperCase());
        p.setName(p.getName().toUpperCase());
        p.setSurname(p.getSurname().toUpperCase());
    }
    return p;
  }

  private void sendResponse(HttpServerExchange exchange, String response){
    exchange.getResponseHeaders()
            .put(Headers.CONTENT_TYPE, "application/json");
    exchange.getResponseSender()
            .send(response);
  }


}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...