Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Channel onUndeliveredElement on JS called when should not #2826

Closed
olme04 opened this issue Jul 16, 2021 · 0 comments
Closed

Channel onUndeliveredElement on JS called when should not #2826

olme04 opened this issue Jul 16, 2021 · 0 comments

Comments

@olme04
Copy link

olme04 commented Jul 16, 2021

When using channel with any buffer size, after filling full buffer with some elements, and then sending even more (those calls will suspend), after receiving first value from buffer, on first element, where send suspends, onUndeliveredElement will be called, and after next receive, onUndeliveredElement will be called on next element and so on, so calling onUndeliveredElement on all elements, that overflow buffer.

Reproducer:

class Resource(val i: Int) {
    var closed = false
    override fun toString(): String = "Resource($i, closed=$closed)"
}

@Test
fun testChannel() = test { //promise on js, runBlocking on jvm
    val channel = Channel<Resource>(3) {
        println("CLOSE: $it")
        it.closed = true
    }

    val job = launch {
        repeat(6) {
            println("RECEIVE - ${channel.receive()}")
        }
    }

    (0..5).map {
        val r = Resource(it)
        async {
            println("SEND: $r")
            channel.send(r)
            println("SENT: $r")
        }
    }.awaitAll()
    job.join()
}

JVM/Native output - expected:

SEND: Resource(0, closed=false)
SENT: Resource(0, closed=false)
SEND: Resource(1, closed=false)
SENT: Resource(1, closed=false)
SEND: Resource(2, closed=false)
SENT: Resource(2, closed=false)
SEND: Resource(3, closed=false)
SENT: Resource(3, closed=false)
SEND: Resource(4, closed=false)
SEND: Resource(5, closed=false)
RECEIVE - Resource(0, closed=false)
RECEIVE - Resource(1, closed=false)
RECEIVE - Resource(2, closed=false)
RECEIVE - Resource(3, closed=false)
RECEIVE - Resource(4, closed=false)
RECEIVE - Resource(5, closed=false)
SENT: Resource(4, closed=false)
SENT: Resource(5, closed=false)

JS (same for browser/node legacy/IR) output - wrong:

SEND: Resource(0, closed=false)
SENT: Resource(0, closed=false)
SEND: Resource(1, closed=false)
SENT: Resource(1, closed=false)
SEND: Resource(2, closed=false)
SENT: Resource(2, closed=false)
SEND: Resource(3, closed=false)
SENT: Resource(3, closed=false)
SEND: Resource(4, closed=false)
SEND: Resource(5, closed=false)
RECEIVE - Resource(0, closed=false)
CLOSE: Resource(4, closed=false)
RECEIVE - Resource(1, closed=false)
CLOSE: Resource(5, closed=false)
RECEIVE - Resource(2, closed=false)
RECEIVE - Resource(3, closed=false)
RECEIVE - Resource(4, closed=true)
RECEIVE - Resource(5, closed=true)
SENT: Resource(4, closed=true)
SENT: Resource(5, closed=true)

Expected result:
There should be no calls to onUndeliveredElement in such case

Env:
kotlinVersion=1.5.21
kotlinxCoroutinesVersion=1.5.1-native-mt

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants