Calling a suspend function from a function block i...
# coroutines
m
Calling a suspend function from a function block in a suspend function doesn’t work
Copy code
private suspend fun outerSuspend() {
    timer(period = 10) {
        innerSuspend() // Error: Suspend functions can be only called within coroutine body
    }
}
It works if I create a new CoroutineScope inside the function block
Copy code
private suspend fun outerSuspend() {
    timer(period = 10) {
        CoroutineScope(<http://Dispatchers.IO|Dispatchers.IO>).launch {
            innerSuspend()
        }
    }
}
Is there a way to use the outer scope in the inner block?
o
in order to do that you need to have
timer
be
inline
or
suspend
itself
2
s
And if that is not possible (timer being inline/suspend), you can do this:
Copy code
private suspend fun outerSuspend() = coroutineScope {
    timer(period = 10) {
        launch { innerSuspend() }
    }
}
Because creating a new
CoroutineScope
, like in your original example’s solution, breaks cancellation/structured-concurrency.
o
hmm, but that does not actually gate the code in the
timer
you would have to explicitly
runBlocking
it to do that (or
runInterruptible
in more recent versions)
s
Yup. But I didn’t think that gating it was needed
g
Just curious what timer does. It looks that it easier to reimplement it with coroutines than try to use non-suspend version of it, also it would make it properly cancellable
s
True. A
Copy code
while (isActive) { 
    innerSuspend()
    delay(periodInMillis)
}
is a straightforward solution.
g
yeah, if it repeat just use delay before or after innerSuspend, and remove while if you don’t need repeat and you just want wait
j
@octylFractal You used the term "gate". What does it mean?
o
basically that it will "escape" outside a normal sequential execution flow, i.e. if the
timer
function was intended to cancel / interrupt / measure the inner block, it would not do so properly because
launch
immediately returns in this case
"gate" is a bit metaphorical in this case, I'm not really sure I could explain it well
j
I think I get it. Thanks @octylFractal!