#micronaut #micronaut-rest
Вопрос:
Проект в micronaut 2.0.1 имеет функцию предоставления некоторого ресурса. Ресурс передается потоком ввода из другой службы по протоколу HTTP.
@ExecuteOn(TaskExecutors.IO)
@Status(HttpStatus.OK)
@Get
public StreamedFile export() throws FileNotFoundException {
InputStream is = service.getFromOtherServiceByHttpCall();
return new StreamedFile(is, CSV_MEDIA_TYPE);
}
К сожалению, приложение перезапускается, потому что конечная точка работоспособности возвращается недостаточно быстро.
Возможно ли, что StreamedFile
блокирует цикл событий при возврате файла через Интернет? Локально все работает.
Редактировать:
Я думаю, что нашел решение для возврата строкового файла, но, к сожалению, оно значительно медленнее.
public Flux<String> export() throws FileNotFoundException {
InputStream is = service.getFromOtherServiceByHttpCall();
return Flux.using(() -> new BufferedReader(new InputStreamReader(is)).lines(),
Flux::fromStream,
BaseStream::close
).subscribeOn(Schedulers.boundedElastic());
Я все еще не понимаю, как правильно передавать байтовый ресурс.
Ответ №1:
Блокировка потока цикла событий может быть вашим случаем, даже если этого не должно произойти, если вы каким-то образом не запускаете только один поток цикла событий.
Тем не менее, вам следует лучше передать содержимое извлеченного файла в другой отдельный поток, используя / StreamedFile
PipedOutputStream
PipedInputStream
:
@Controller("/file")
public class FileHandlerController {
private ExecutorService ioExecutor;
private OtherService service;
public FileHandlerController(@Named("io") ExecutorService executorService, OtherService service) {
this.ioExecutor = executorService; // make sure to pipe on a separate thread so that the file gets returned immediately
this.service = service;
}
@Status(HttpStatus.OK)
@Get
public StreamedFile export() throws FileNotFoundException {
PipedOutputStream output = new PipedOutputStream();
PipedInputStream input = new PipedInputStream(output);
executorService.execute(() -> {
InputStream is = service.getFromOtherServiceByHttpCall();
int b;
while((b = is.read()) != -1) {
output.write(b);
}
output.flush();
output.close();
});
return new StreamedFile(input, CSV_MEDIA_TYPE);
}
}