AsyncHttpClient создает сколько потоков? - PullRequest
0 голосов
/ 28 мая 2019

Я использую асинхронный http-клиент в своем коде для асинхронной обработки ответов GET. Я могу одновременно выполнить 100 запросов.

Я использую только экземпляр httpClient в контейнере

@Bean(destroyMethod = "close")
open fun httpClient() = Dsl.asyncHttpClient()

Код выглядит как

fun method(): CompletableFuture<String> {
    return httpClient.prepareGet("someUrl").execute()
        .toCompletableFuture()
        .thenApply(::getResponseBody)
}

Функционально работает нормально.В своем тестировании я использую макет конечной точки с тем же адресом URL.Но я ожидал, что все запросы обрабатываются в нескольких потоках, но в профилировщике я вижу, что для AsyncHttpClient создано 16 потоков, и они не уничтожаются, даже если нет запросов на отправку.

profiler screenshoot

Я ожидал, что

  • будет меньше потоков для асинхронного клиента
  • потоки будут уничтожены после некоторого настроенного тайм-аута
  • есть ли какая-нибудь опция для контроля того, сколько потоков может быть создано asyncHttpClient?

Я что-то упускаю в своих ожиданиях?

UPDATE 1 Я видел инструкцию по https://github.com/AsyncHttpClient/async-http-client/wiki/Connection-pooling Я не нашел информации о пуле потоков

ОБНОВЛЕНИЕ 2 Я также создал метод, чтобы сделать то же самое, но с обработчиком и дополнительным пулом исполнителя

Служебный метод выглядит как

fun <Value, Result> CompletableFuture<Value>.handleResultAsync(executor: Executor, initResultHandler: ResultHandler<Value, Result>.() -> Unit): CompletableFuture<Result> {
    val rh = ResultHandler<Value, Result>()
    rh.initResultHandler()

    val handler = BiFunction { value: Value?, exception: Throwable? ->
        if (exception == null) rh.success?.invoke(value) else rh.fail?.invoke(exception)
    }

    return handleAsync(handler, executor)
}

Обновленный метод выглядит как

fun method(): CompletableFuture<String> {
    return httpClient.prepareGet("someUrl").execute()
        .toCompletableFuture()
        .handleResultAsync(executor) {
            success = {response ->
                logger.info("ok")
                getResponseBody(response!!)
            }
            fail = { ex ->
                logger.error("Failed to execute request", ex)
                throw ex
            }
    }
}

Тогда я вижу, что результат метода GET выполняется в потоках, предоставленных пулом потоков(ранее результатt был выполнен в «AsyncHttpClient-3-x»), но дополнительный поток для AsyncHttpClient все еще создается и не уничтожается.

...