-
-
Save ScottPierce/0e687021f34d779708d1f32bfc81e8e2 to your computer and use it in GitHub Desktop.
MutabilityException
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.example.abtest | |
import co.touchlab.stately.freeze | |
import kotlinx.coroutines.CoroutineScope | |
import kotlinx.coroutines.channels.Channel | |
import kotlinx.coroutines.delay | |
import kotlinx.coroutines.flow.Flow | |
import kotlinx.coroutines.flow.collect | |
import kotlinx.coroutines.flow.emitAll | |
import kotlinx.coroutines.flow.flow | |
import kotlinx.coroutines.flow.flowOn | |
import kotlinx.coroutines.flow.onCompletion | |
import kotlinx.coroutines.flow.onEach | |
import kotlinx.coroutines.flow.receiveAsFlow | |
import kotlinx.coroutines.launch | |
import kotlinx.coroutines.newSingleThreadContext | |
import kotlinx.coroutines.runBlocking | |
import kotlin.test.Test | |
class InitTest { | |
@Test | |
fun test1() { | |
runBlocking(Contexts.context2) { | |
flowCallbackWrapper { | |
println("Callback: $it") | |
} | |
} | |
runBlocking(Contexts.context1) { | |
delay(5000) | |
} | |
} | |
@Test | |
fun test2() { | |
runBlocking(Contexts.context1) { | |
flow1().collect { | |
println("Flow: $it") | |
} | |
} | |
} | |
fun flowCallbackWrapper( | |
callback: (value: String) -> Unit | |
) { | |
callback.freeze() | |
CoroutineScope(Contexts.context2).launch { | |
flow1().collect { | |
callback(it) | |
} | |
} | |
} | |
fun flow1(): Flow<String> = flow { | |
var isEmpty = true | |
emitAll( | |
AsyncExample().getData() | |
.onEach { isEmpty = false } | |
.onCompletion { | |
if (isEmpty) { | |
emit("Default") | |
} | |
} | |
) | |
} | |
} | |
object Contexts { | |
val context1 = newSingleThreadContext("1") | |
val context2 = newSingleThreadContext("2") | |
} | |
class AsyncExample { | |
private val channel = Channel<suspend (delegate: Example) -> Unit>() | |
init { | |
CoroutineScope(Contexts.context2).launch { | |
val delegate = Example() | |
channel.receiveAsFlow().collect { | |
it(delegate) | |
} | |
} | |
freeze() | |
} | |
suspend fun getData(): Flow<String> = flow { | |
channel.send { | |
emitAll(it.getData()) | |
} | |
}.flowOn(Contexts.context2) | |
} | |
class Example { | |
fun getData(): Flow<String> = flow { | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
test1
andtest2
are driven by the same code, excepttest1
wraps a suspend function with a callback. Why doestest1
have this exception, buttest2
doesn't?If I comment out
test2
and run `test1, I'll see the following exception in the standard output, but the test still passes: