Apache HttpAsyncClient и CountDownLatch

Как правильно обрабатывать различные случаи исключений при использовании apache htttpasyncclient? Рассмотрим следующий псевдокод, основанный на этом пример, где я добавил потребительский параметр в вызов execute. Намерение состоит в том, чтобы сделать асинхронный HTTP-запрос, в котором данные обрабатываются как поток, когда приходят байты, а не ждут полного ответа перед обработкой. Могут возникнуть различные проблемы, такие как исключение тайм-аута в HTTP-запросе, сбой подключения (может быть, нет сети) и т. д. Всегда ли гарантируется, что, например, по тайм-ауту с ответом, не возвращающимся вовремя, что releaseResources() всегда называется. Вопрос в том, где в приведенном ниже коде нужно поместить latch.countDown(), чтобы всегда гарантировать, что вызов await не просто зависнет, независимо от того, какое исключение. Достаточно ли вызова latch.countDown() в StreamConsumer.releaseResources() для предотвращения зависания ожидания?

public static void main(final String[] args) throws Exception {
    client.execute(HttpAsyncMethods.createGet(u), new StreamConsumer(...), new FutureCallback<Boolean>() {
        @Override
        public void cancelled() {
            // Is latch call needed here?
            // latch.countDown();
        }

        @Override
        public void completed(Boolean response) {
            // Is latch call needed here?
            // latch.countDown();
        }

        @Override
        public void failed(Exception e) {
            // Is latch call needed here?
            // latch.countDown();
        }
    });

    latch.await();
}


static class StreamConsumer extends AsyncByteConsumer<Boolean> {
    @Override
    protected void onResponseReceived(final HttpResponse response) {
       latch.countDown();
    }

    @Override
    protected void onByteReceived(final ByteBuffer buf, final IOControl ioctrl) throws IOException {

    }

    @Override
    protected void releaseResources() {
        latch.countDown();
    }

}

person user782220    schedule 05.03.2019    source источник


Ответы (1)


Метод CloseableHttpAsyncClient#execute завершает работу сразу после отправки запроса в конвейер выполнения запросов и возвращает объект Future, представляющий будущий результат операции.

Поэтому защелка в примере необходима, чтобы клиент не отключился сразу после CloseableHttpAsyncClient#execute вызова.

Если кто-то использует CloseableHttpAsyncClient как синглтон с определенным жизненным циклом (как и следует), синхронизация завершения запроса и завершения работы клиента может быть ненужной.

person ok2c    schedule 06.03.2019