I’m trying to figure out the right way to use Kotlin coroutines in Kotlin 1.3 and it seems there are a lot of ways to do it wrong, even when it all “seems to work”.
I learned today that I have to write my suspending functions like this:
suspend fun get(id: Long): KalahGame = coroutineScope {
val game = async {
// ... Do things
}
game.await()
}
Instead of like this:
suspend fun get(id: Long): KalahGame {
val game = async {
// ... Do things
}
return game.await()
}
The difference is quite subtle, I had overlooked the crucial = coroutineScope
part at first, and it all appeared to work - until this function threw an error because the given ID was not found.
Then, the next invokation of any other coroutine in the same object always resulted in the same exception being rethrown!
I know it was the same exception over and over again from looking at the line numbers, which didn’t match the method being called.
This was really confusing and it was only by luck that this morning I spotted the difference when re-reading Roman Elizarov’s blogpost on Kotlin structured concurrency.
Now I’m wondering, what else am I doing wrong in my code?
coroutineScope { ... }
can be used only with a suspending function it seems.
Is it then safe to use `launch { … } in a non-suspending function, when another coroutine-scope is already active from the caller?
From a launch { ... }
block, can I safely call a function defined as:
suspend fun AmazonKinesisFirehoseAsync.putRecordAsyncAwait(putRecordRequest: PutRecordRequest): PutRecordResult = suspendCoroutine { continuation ->
// Do things
}
Or should I put coroutineScope { ... }
around that too?
(In the case of that project I’m calling from the topmost coroutine context, in case it makes any difference).
These are all things which I haven’t managed to pick up from the documentation, and looking at code examples from other people does more harm than good, since most of them are based on the older experimental coroutine library does show one the incorrect, unsafe way of doing things.
It feels to me that the documentation should be clearer and show fuller examples, and should also do a better job of showing people what is wrong vs what is right.
It would be nice also, if it wasn’t so easy to do things horribly wrong with such confusing results…
Perhaps some extra inspections in IntelliJ would help?
–Tim