Hong Phuc
11/02/2025, 7:42 AMConcurrent read attempts mean? I'm trying to read a file in this function where this error happened.
2025-11-02 07:39:59.407 [eventLoopGroupProxy-4-3] ERROR Application - Unhandled exception caught for CoroutineName(call-handler)
Nov 02 07:39:59 backend-server java[675297]: io.ktor.utils.io.ConcurrentIOException: Concurrent read attempts
Nov 02 07:39:59 backend-server java[675297]: at io.ktor.utils.io.ByteChannel.awaitContent(ByteChannel.kt:272)
Nov 02 07:39:59 backend-server java[675297]: at io.ktor.utils.io.ByteReadChannel$DefaultImpls.awaitContent$default(ByteReadChannel.kt:30)
Nov 02 07:39:59 backend-server java[675297]: at io.ktor.utils.io.ByteReadChannelOperationsKt.discard(ByteReadChannelOperations.kt:349)
Nov 02 07:39:59 backend-server java[675297]: at io.ktor.utils.io.ByteReadChannelOperationsKt.discard$default(ByteReadChannelOperations.kt:344)
Nov 02 07:39:59 backend-server java[675297]: at io.ktor.server.engine.DefaultEnginePipelineKt$defaultEnginePipeline$1.invokeSuspend(DefaultEnginePipeline.kt:42)
Nov 02 07:39:59 backend-server java[675297]: at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
Nov 02 07:39:59 backend-server java[675297]: at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:99)
Nov 02 07:39:59 backend-server java[675297]: at kotlinx.coroutines.EventLoop.processUnconfinedEvent(EventLoop.common.kt:65)
Nov 02 07:39:59 backend-server java[675297]: at kotlinx.coroutines.internal.DispatchedContinuation.resumeWith(DispatchedContinuation.kt:327)
Nov 02 07:39:59 backend-server java[675297]: at io.ktor.util.pipeline.SuspendFunctionGun.resumeRootWith(SuspendFunctionGun.kt:149)
Nov 02 07:39:59 backend-server java[675297]: at io.ktor.util.pipeline.SuspendFunctionGun.loop(SuspendFunctionGun.kt:134)
Nov 02 07:39:59 backend-server java[675297]: at io.ktor.util.pipeline.SuspendFunctionGun.proceed(SuspendFunctionGun.kt:89)
Nov 02 07:39:59 backend-server java[675297]: at io.ktor.util.pipeline.SuspendFunctionGun.execute$ktor_utils(SuspendFunctionGun.kt:109)
Nov 02 07:39:59 backend-server java[675297]: at io.ktor.util.pipeline.Pipeline.execute(Pipeline.kt:86)
Nov 02 07:39:59 backend-server java[675297]: atAleksei Tirman [JB]
11/03/2025, 9:00 AMHong Phuc
11/03/2025, 11:28 PMmultiPart.forEachPart { part ->
when (part) {
is PartData.FileItem -> {
val fileName = UUID.randomUUID().toString() + "_" + part.originalFileName
val partStream = part.provider().toInputStream()
val filePath = "uploads/$fileName"
val file = File(filePath)
// Use input stream to save the file
saveImageToDisk(file, part)
saveImageToS3(partStream, fileName, file, s3Client)
val outputName = UUID.randomUUID().toString() + ".mp4"
val outputPath = "uploads/$outputName"
convertImageToVideo(filePath, outputPath)
val contentID = UUID.randomUUID().toString()
val outputVideoPath = "uploads/$contentID.mp4"
val outputManifestPath = "uploads/$contentID-manifest"
val encryptedVideoInputStream = FileInputStream(outputVideoPath)
encryptedVideoInputStream.use {
val replayableStream = ByteStream.fromInputStream(encryptedVideoInputStream)
val s3ObjectRequest = PutObjectRequest {
key = outputVideoPath
body = replayableStream
contentType = "application/mp4"
acl = ObjectCannedAcl.PublicRead
}
s3Client.putObject(s3ObjectRequest)
}
val manifestFile = FileInputStream(outputManifestPath)
manifestFile.use { manifest ->
val replayableStream = ByteStream.fromInputStream(manifest)
val s3ObjectRequest = PutObjectRequest {
key = widevineOutputManifestPath
body = replayableStream
contentType = "text/plain"
acl = ObjectCannedAcl.PublicRead
}
s3Client.putObject(s3ObjectRequest)
}
here it isAleksei Tirman [JB]
11/04/2025, 7:11 AMsaveImageToDisk and saveImageToS3 methods which cause the exception.Hong Phuc
11/04/2025, 10:44 AMfun saveImageToDisk(file: File, part: PartData.FileItem) {
val output = file.outputStream()
val input = part.provider().toInputStream()
input.copyTo(output)
try {
input.close()
output.close()
} catch (e: Exception) {
println(e)
}
}
suspend fun saveImageToS3(partStream: InputStream, fileName: String, file: File, s3Client: S3Client) {
partStream.use { stream ->
val replayableStream = ByteStream.fromInputStream(file.inputStream())
val s3ObjectRequest = PutObjectRequest({
key = fileName
body = replayableStream
contentType = "image/jpeg"
})
s3Client.putObject(s3ObjectRequest)
}
}
one is reading from the file and the other is writing to it. But I can't see where they concurrently try to read the fileAleksei Tirman [JB]
11/04/2025, 12:42 PMpartStream is passed to the saveImageToS3 function. I suggest putting a breakpoint inside the ByteChannel.awaitContent method to find out the caller stack traces.Hong Phuc
11/04/2025, 2:25 PMpartStream into there, must have been some kind of mistake