Coroutine async exception confusion when suspend function is involved

Not for the synchronous consumer, anything deferred is still in a coroutine and await can’t be called outside that. So, imagine you are working with Java or and existing project and you need to call a coroutine based Kotlin library, get some data and process it.

How about better and documented futures examples? Yes there is some info out there, but the examples in GitHub are not documented. I see with coroutines-jdk8 there is something, but boy is there little info on that beyond the KDoc in the code. I would much rather have java deal with a CompletableFuture instead of a result from runBlocking, but right now runBlocking is the easiest.

Totally agree, thank you. How about Java futures coroutines-jdk8? I watched multiple JetBrains Kotlin videos mentioning how they could work together and it was a goal of the implementation, so why not show how these worlds collide? instead of runBlocking.

I am getting the hang of it and it is not complicated, but there is so much miss information and poor explanations that lead you down the wrong path.

If delay and println are your goal :wink: :stuck_out_tongue:

Delays and prints are good, because they are simple and can’t be misunderstood. We can create documentation by providing business cases, but then it would be like: 15 minutes of explaining the case and 1 minute of explaining how to apply coroutines to it. Also, there is a risk the reader misunderstands the case or that they don’t know this specific network library that was used in the example, so they have to learn network library only to understand coroutines docs. And at the end of this you can always say: “Ok, they explained how to make a blocking network call, but there are still no examples on how to make a blocking file read.”.

This is another thing that I would like to see in “How to integrate with existing code?” docs. The answer is actually very easy, just use scope.future { }, deferred.asCompletableFuture() or future.asDeferred() and this is all you need. I believe this was not mentioned anywhere in the guide.

On the other hand, I never had problems finding such information. Nowadays, we have awesome IDEs, so you just start writing “futu…” and IDE already shows you asCompletableFuture() function, so for me it is hard to not find it. The only tricky part in this specific case is that this is a separate lib.

I disagree, a simple suspend function call from a library is all it takes. It could even be a mythical library. Example:

gqlClient.query(OrangesQuery()).execute()

The above is a suspend function call. Show that being used from a coroutine builder and then show its results being consumed by sync code. One explanation is needed the return value is a data class or pojo. Doesn’t need a book. Also show it being cancelled if it takes too long. Show exceptions being handled from it, etc.

No comments, no explanation, nothing. Not really good examples if you ask me.

You are aware that not everyone even heard about GraphQL and they don’t know what is this cryptic gqlClient? And how can I know what these query() and execute() do exactly? I assume query() only prepares a request and execute() performs the operation, but this is just an assumption and it might be wrong. Also, it is not clear from the code itself whether execute() is blocking, suspending or asynchronous, so it would be good to provide at least the signature of execute() (yes, you mentioned it suspends).

This is exactly what I mean. At least for me the easiest to read and understand is to create a dummy function like:

suspend fun doNetworkCall(): String {
    delay(1000)
    return "OK"
}

And then use this function in the example. It requires no knowledge about anything and has no parts that might be unclear to anyone. Also, it allows the reader to copy the code, run it and experiment with it. Your above example is totally useless if we want to see the results by ourselves - it is not possible to even run it.

Dummy function with empty body is also fine, because we can easily fill it with some delays, etc. Your example is much harder to experiment with, because it is more complicated.

edit:
Earlier in this topic you provided example from Kotlin docs:

val token = preparePost()
val post = submitPost(token, item)
processPost(post)

Then you said you can’t understand this example, because you don’t know what is this processPost(). Now you provide a very similar example and say this is the way to go.

Not for the synchronous consumer

Synchronous consumer? For synchronous consumer (non-coroutine) it always end up with runBlocking, I don’t think that there are any different ways, which as I pointed out is mentioned in doc. So want to use blocking API, use runBlocking, want to use asynchronous API use any adapter for Java async APIs such as CompletableFuture, RxJava, Reactor

CompletableFuture instead of a result from runBlocking, but right now runBlocking is the easiest.

There is only this doc, but what kind additional example you need? It shows use case, there is just a couple of functions for whole library: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-jdk8/index.html

Thanks all for the replies. I am done, had enough, goodbye Kotlin it is not worth the hassle.