Youssef Shoaib [MOD]
05/03/2024, 1:43 PMstartCoroutineUndispatched
public or accessible in some way? I can use CoroutineStart.invoke
with an opt-in, but of course that opt-in scares me! I want something slightly more "elegant" for lack of a better word than:
launch(start = CoroutineStart.UNDISPATCHED) { continuation.resumeWith(runCatching { f(receiver) })
Dmitry Khalanskiy [JB]
05/03/2024, 1:53 PMstartCoroutineUndispatched
being useful in some typical use cases. What is the end goal of the code you provided?Youssef Shoaib [MOD]
05/03/2024, 1:58 PMsuspendCoroutine
), I'd like to optimize that first call. I can do that in a different way of course like e.g. taking the arguments of that first call as a parameter, but that's inelegant. I can also do the launch as above, but I'm concerned that that might not have the right semanticsDmitry Khalanskiy [JB]
05/03/2024, 2:02 PMyourFunction {
delay(1.seconds)
anotherFunctionOfYours()
}
should suspend in anotherFunctionOfYours
, but
yourFunction {
println("not going to suspend")
anotherFunctionOfYours()
println("told you!")
}
shouldn't?Youssef Shoaib [MOD]
05/03/2024, 4:50 PMsuspend fun anotherFunctionOfYours(param: Blah) = suspendCoroutine { //store cont and param }
then yourFunction
should do something special. `yourFunction`s to a previous isn't suspend, and in fact it connects the block it got passed to a previous continuation. Basically, if it doesn't get that first call, it has to terminate execution and wait until it gets called (because it needs the param
value), but if it does get that first call, it can go on a faster path where it uses the param
value immediately.Youssef Shoaib [MOD]
05/03/2024, 4:53 PMyourFunction {
delay(1.seconds)
anotherFunctionOfYours(blahCalculationThatMightBeSuspend())
}
and this one on the fast path:
yourFunction {
println("not going to suspend")
anotherFunctionOfYours(42)
println("continuation got resumed")
}
and the point is to capture that blah
parameter if it's sync-ly available, but if not we can wait for it (this sounds so suspiciously similar to how suspension works, I know. I'm experimenting with making delimited continuations using Compose, hence why I'm going deep into coroutine machinery)Dmitry Khalanskiy [JB]
05/04/2024, 7:13 AMsuspend fun yourFunction(block: suspend Registrator.() -> Unit) {
val registrator = Registrator()
coroutineScope {
launch(start = CoroutineStart.UNDISPATCHED) {
registrator.block()
}
if (registrator.hasRegistered) {
// we entered the fast path
} else {
// we suspended before registering
}
}
}
fun Registrator.anotherFunctionOfYours(value: Int) {
register(value)
}
Youssef Shoaib [MOD]
05/04/2024, 11:37 AMyourFunction
is not suspend, and block
is used to resume another Continuation (and hence block.startCoroutine(registrator, continuation)
is the perfect call here).
Also, anotherFunctuonOfYours
looks more like this:
suspend fun Registrator.anotherFunctionOfYours(value: Int) {
register(value)
suspendCoroutine {
this.continuation = it
}
}
Zach Klippenstein (he/him) [MOD]
05/04/2024, 6:54 PM