0

I have a Ktor application that return multiple files as a stream but when the client has a slow internet connection, apparently, the stream gets full and blows launching an io.netty.handler.timeout.WriteTimeoutException.

kotlinx.coroutines.JobCancellationException: Parent job is Cancelling                                    
Caused by: io.netty.handler.timeout.WriteTimeoutException: null 

Is there a way to prevent that ?

Here's my method:

suspend fun ApplicationCall.returnMultiFiles(files: List<StreamFile>) {
        log.debug("Returning Multiple Files: ${files.size}")
        val call = this  // Just to make it more readable
        val bufferSize = 16 * 1024

        call.response.headers.append(
            HttpHeaders.ContentDisposition,
            ContentDisposition.Attachment.withParameter(ContentDisposition.Parameters.FileName, "${UUID.randomUUID()}.zip").toString())

        call.respondOutputStream(ContentType.parse("application/octet-stream")) {
            val returnOutputStream = this.buffered(bufferSize) // Just to make it more readable

            ZipOutputStream(returnOutputStream).use { zipout ->
                files.forEach{ record ->
                    try {
                        zipout.putNextEntry(ZipEntry(record.getZipEntry()))
                        log.debug("Adding: ${record.getZipEntry()}")
                        record.getInputStream().use { fileInput ->
                            fileInput.copyTo(zipout, bufferSize)
                        }
                    } catch (e: Exception) {
                        log.error("Failed to add ${record.getZipEntry()}", e)
                    }
                }
            }
        }
    }
ademarizu
  • 845
  • 1
  • 8
  • 18
  • Could you please describe how exactly to reproduce the `WriteTimeoutException`? – Aleksei Tirman Sep 27 '21 at 19:19
  • All I did was try downloading large files with slow network. – ademarizu Sep 27 '21 at 20:09
  • I can't reproduce the `WriteTimeoutException` but you could try to completely remove write timeout: `embeddedServer(Netty, port = 8080, configure = { responseWriteTimeoutSeconds = -1 }) {}`. Here https://ktor.io/docs/engines.html#netty you can see an example. – Aleksei Tirman Sep 28 '21 at 07:01

0 Answers0