I am using spring boot application with REST API export csv file using PipedOutputStream. But when I hit the REST API end point then it is getting locked on 100th row without any exception until I force reloading of application (java.io.PipedInputStream.awaitSpace). Logs are below.
What I know is that it must be in separated thread and hence I decided to put @Async annotation to exportCsv() method. So I suppose that this should be executed in separated thread.
Questions
- How may I force to handle this operation in try catch block?
- Why is it getting locked when it is in separated thread? Is my understanding correct that pin is just returned to end user while it is connected to pout as PipedOutputStream during write processing?
Here is sample code
End point class
public ResponseEntity<InputStreamResource> exportCsv(Long id) {
PipedInputSTream pin = new PipedInputSTream();
PipedOutputStream pout = new PipedOutputStream(pin);
service.exportCsv(pout, id);
return ResponseEntity.ok().headers(headers).contentType(mediaType).body(new InputStreamResource(pin));
}
---
Service class
@Async
void exportCsv(OutputStream outputStream, Long id) {
BeanWriter writer = StreamFactory.newInstance().createWriter("output", new OutputStreamWriter(outputStream));
AtomicInteger index = new AtomicInteger();
try (Stream<Data> stream = repository.streamData(id)) {
stream.filter(Objects::nonNull).forEach(e -> {
writer.write(e);
int i = index.incrementAndGet();
if (i % FLUSH_SIZE == 0) writer.flush(); System.gc();
});
}
writer.flush(); writer.close();
}
Here is log
main" prio=10 tid=0x08066000 nid=0x48d2 in Object.wait() [0xb7fd2000..0xb7fd31e8]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0xa5c28be8> (a java.io.PipedInputStream)
at java.io.PipedInputStream.awaitSpace(PipedInputStream.java:257)
at java.io.PipedInputStream.receive(PipedInputStream.java:215)