Description
Describe the bug
I'm attempting to parse an InputStream
from an Android BluetoothSocket
. The Bluetooth device on the other end sends a whitespace-separated stream of JSON entries. The end-of-stream only happens once the app disconnects from the Bluetooth device. These entries are responses to requests sent by the app.
The issue is that until a certain amount of data arrives from the Bluetooth device, decodeToSequence
won't produce even a single entry. The typical size of a JSON entry sent by the device is around 100 bytes. I would like to process it as soon as it arrives.
To Reproduce
@OptIn(ExperimentalSerializationApi::class)
@Test
fun decodeFromStreamPreloadBug() {
@Serializable
data class MyResponse(val contents: String)
val source = PipedOutputStream()
val producer = Executors.newSingleThreadExecutor()
producer.submit {
for (i in 0 until 500) {
source.write(Json.encodeToString(MyResponse("lorem ipsum")).toByteArray(Charsets.UTF_8))
}
}
val sink = PipedInputStream(source)
val seq = Json.decodeToSequence<MyResponse>(sink, DecodeSequenceMode.WHITESPACE_SEPARATED)
for (response in seq) {
println(response)
}
}
This code blocks indefinitely, on the val seq = ...
line. If I change the number of messages sent by the producer from 500 to 700, it prints 625 responses, then blocks indefinitely.
Pretty sure the issue is in the initial call of ReaderJsonLexer::preload.
Expected behavior
Get the next entry from the Bluetooth device as soon as it arrives.
Environment
- Kotlin version: 1.7.20
- Library version: 1.4.1
- Kotlin platforms: JVM (Android)
- Gradle version: no idea. Whatever is used by the Android Gradle Plugin 7.3.0
- IDE version: Android Studio Dolphin 2021.3.1