Skip to content

decodeToSequence won't start parsing until 16k bytes of data arrives #2074

Open
@kustra

Description

@kustra

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions