Загрузка большого результата

Можно ли использовать декларативный клиент для загрузки большого результата, например, используя InputStream? Я пробовал подпись клиента как

HttpResponse<InputStream> getQueryResult(String jobId, String resultId);

Но он пытается загрузить все тело, что затем приводит к

io.micronaut.http.client.exceptions.ContentLengthExceededException: The received length exceeds the maximum content length 

Заранее спасибо.

1 ответ

Решение

Здесь происходит то, что ваш клиент запрашивает полностью полученный (агрегированный) HttpResponse, оборачивая байтовый массив, который затем преобразуется в InputStream. Чтобы получить байты ответа без агрегирования, вам необходимо запросить один из реактивных типов, например org.reactivestreams.Publisher (или его подходящий подкласс) ByteBuffers. Тогда вам нужно обработать их.

Пример:

Flowable<ByteBuffer<?>> getQueryResult(String jobId, String resultId);

Вы можете запустить map, forEach, blockingForEachи т. д. на этом io.reactivex.Flowable - НО ПОМНИТЕ, ЧТОБЫ СВОБОДИТЬ БУФЕРЫ, или вы создадите много мусора и получите неприятные сообщения в журналах. Пример (в Groovy):

Flowable<ByteBuffer<?>> responseFlowable = myClient.getQueryResult("job1", "foo")
int sum = 0
responseFlowable.blockingForEach { ByteBuffer byteBuffer ->
    sum += byteBuffer.toByteArray().count('!')
    ((ReferenceCounted)byteBuffer).release() // Let Netty do its thing!
}

(Очевидно, что блокирование плохо для высокой пропускной способности, но это только пример)

Надеюсь, это поможет.

Другие вопросы по тегам