-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Open
Description
Expected Behavior
Usercase: receiving big entries from database I try to compress them and return as a StreamedFile with minimal memory usage.
@Controller
class Controller {
@Get("/download", produces = [MediaType.APPLICATION_OCTET_STREAM])
suspend fun download(): StreamedFile = coroutineScope {
provide()
}
suspend fun provide(): StreamedFile = coroutineScope {
val inputStream = PipedInputStream(1024 * 10)
val outputStream = PipedOutputStream(inputStream)
launch(Dispatchers.Default) {
outputStream.use { stream ->
ZipOutputStream(stream).use { stream ->
(0 until 1000).forEach { i ->
println("Processing entry $i")
stream.putNextEntry(ZipEntry("$i.txt"))
ByteArrayInputStream(getRandomString(1024).toByteArray()).use { it.copyTo(stream) }
stream.closeEntry()
println("Processing entry $i complete")
}
}
}
println("Coroutine complete.")
}
println("Returning streaming file stub")
StreamedFile(inputStream, MediaType.APPLICATION_OCTET_STREAM_TYPE)
.attach("export.zip")
}
private fun getRandomString(length: Int): String {
val allowedChars = ('A'..'Z') + ('a'..'z') + ('0'..'9') + ' '
return String(CharArray(length) { allowedChars.random() })
}
}
Actual Behaviour
Stream is not read, leading to PipedInputStream overflow, hanging the entire process.
Steps To Reproduce
Start the attached project and try to download file from /download If generated content doesn't fit PipedInputStream, the process hangs.
- Returning streaming file stub is visible, meaning that stream is passed and data pump has started in another thread
- Several Processing entry $i complete is visible. Corresponds to buffer size and entries size
- Coroutine complete. is not visible
Environment Information
FreeBSD 14.3
OpenJDK21
Example Application
Version
4.9.3
Metadata
Metadata
Assignees
Labels
No labels