https://kotlinlang.org logo
#coroutines
Title
# coroutines
n

Nikiizvorski

07/15/2021, 1:45 PM
Hey guys, i have the following snippet and would really appreciate some help. So basically this function is being called from another coroutine but this one is blocking even after everything else returns and it’s done so it’s like it never finish. Do you guys see something wrong with it? When i comment it out everything else works fine.
override suspend fun waitForFix(timeoutMsec: Long, scope: CoroutineScope): Location? {
return getLocation() ?: let {
val channel = Channel<Location?>(1)
val timeout = scope.launch {
delay(timeoutMsec)
channel.send(null)
}
getUpdates { fix ->
scope.launch {
timeout.cancel()
channel.send(fix)
}
}
channel.receive()
}
}
o

Oliver.O

07/15/2021, 2:04 PM
Probably
getUpdates()
is blocking and does not support cancellation. If it were cancellable, you might want to use
withTimeout { ... }
instead of your channel-based solution. See https://stackoverflow.com/a/47641886/2529022
n

Nikiizvorski

07/15/2021, 2:06 PM
I was thinking about that thanks i will look into it. Usually that’s just a location fetch. But i will try to replace it withTimeout should be better.
So i was thinking how it would if i change them to trySend and tryReceive it should be good then right
I have ended up with this solution which seem’s to work quite fine for me. Tested it and seem’s not to block anymore.
Copy code
withTimeout(timeoutMsec) {
    getUpdates { fix ->
        scope.launch {
            channel.trySend(fix)
        }
    }
    channel.receive()
}
o

Oliver.O

07/15/2021, 5:15 PM
As
trySend()
is non-blocking, you can avoid the overhead of an extra coroutine:
Copy code
getUpdates { channel.trySend(it) }
should do just fine.
n

Nikiizvorski

07/15/2021, 5:16 PM
Yes you are right. Was a bit tired didn't even see it. 😴 Thank you Oliver!
😆 1
2 Views