https://kotlinlang.org logo
Title
e

eygraber

10/20/2017, 6:41 PM
Hello all, I've been reading the docs and the KEEP, but I'm not sure I fully understand what coroutines offer. The example I've been keeping in my head is a server that responds to all requests with a randomly selected quote that it retrieves from a remote service. The call to that service and the response sent back to the client is done on a separate thread than the one the request comes in on. Using vanilla executors we would pass a
Runnable
that makes the network call and writes the response. Using Rx it would look something like:
quoteService
    .getQuote()
    .flatMap(response::write)
    .subscribeOn(<http://Schedulers.io|Schedulers.io>())
    .subscribeBy(
      onSuccess = {},
      onError = {}  
    )
I'm not great with coroutines, but I assume it would look something like:
async {
  try {
    val quote = quoteService.getQuote().await()
    response.write(quote)
  catch(_: Exception) {}
}
Is it just about the style of programming, or do coroutines offer something major over the other approaches? I see a few places that mention coroutines are non-blocking, but they don't seem to be, at least not in the same way that non-blocking io works. Can anyone help clarify this?
v

voddan

10/20/2017, 7:39 PM
In your example you have only one request and only one quote. But usually the logic is much more complicated. For example how would you implement a service that send back multiple quotes depending on the content of the request or the data in BD. In RX loops and ifs are hard. In coroutines they are just loops and conditions.
In other words, I suggest you try a messier example
u

uli

10/20/2017, 8:16 PM
Coroutines are not themselves non-blocking. They are rather an abstraction for non-blocking things that enable you to write sequential code around non-blocking things while these non-blocking things share one or more threads.
Take a look at this example. It handles many clients, using non-blocking io on a limited number of threads using a sequential programming style: https://github.com/Kotlin/kotlinx.coroutines/blob/master/integration/kotlinx-coroutines-nio/src/test/kotlin/examples/echo-example.kt
The non-blocking calls and their succeeding callbacks are simply turned into a suspendable function which will release the thread it is running on while waiting for the callback
e

eygraber

10/20/2017, 9:53 PM
Thanks for the replies, but I feel like they're answering if I should use co-routines over other approaches. My actual question better worded would be, aside from style of coding, is there anything that co-routines provides over another approach (e.g. rx)? Better performance, more throughput, etc... Or are they all just building blocks that are shaped differently?
v

voddan

10/21/2017, 4:45 AM
Better performance, more throughput, etc,
Coroutines cover more use cases than RX, for example
yield
. I guess you could also get more performance if running coroutines in a single thread. Anyways what you call
style of coding
, and what I call
different abstraction
, is the main benefit of Coroutines, and all else are just bonuses.
u

uli

10/21/2017, 7:30 AM
Or all goes together. The story goes more like non-blocking io for example give much better scalebility then blocking, because you don't need massive amount of threads for a massive amount of connections. But non-blocking io is hard to get right. That's why people often don't use it. With coroutines non-blocking paradigms become feasible in a lot more contexts. So the answer is, if you are doing the same things as in eg. Rx, there will be no hard benefits. But you might start doing things that were to complex before. And these things might come with hard benefits.
4
e

eygraber

10/22/2017, 5:09 AM
Interesting. I feel like it's presented as providing hard benefits over other approaches, which was really confusing to me. I could see how it might make some use cases more simple than, let's say, Rx, but I'm not sure if it's worth changing the abstraction that I use overall. Knowing what I do now, I'd most likely continue using Rx predominantly, and dip into co-routines for specialized cases.
r

rocketraman

10/22/2017, 5:42 AM
In the end, all concurrent software runs on the same hardware, so none really has "hard benefits" over any other in the way you are using the term. A quote comes to mind though:
"When the only tool you know is a hammer, everything looks like a nail."
I think you would benefit from some time learning some additional tools beyond your rx hammer (and coroutines is a powerful one with multiple sub-tools... I'd at least add actors and good old shared state to the mix as well), so you can recognize which problems require which solutions.