Will Kotlin coroutine always run on same thread? If not then how can we make it work with Guice Request Scope semantics? - kotlin

Request scope enables us to track request wise variables throughout the request processing. But I think it depends on thread local variables. I assume using Kotlin coroutines will that break the Guice Injection of Request Scope semantics..

Coroutines do not always run on the same thread and therefore you will have problems with thread local variables, e.g. Guice Request Scope.
But it is possible to transfer thread local variables between coroutines: https://github.com/Kotlin/kotlinx.coroutines/blob/master/docs/coroutine-context-and-dispatchers.md#thread-local-data
I don't know Guice and so I don't know if there is a way to integrate ThreadContextElement into this framework.
See also: How to use code that relies on ThreadLocal with Kotlin coroutines

Related

Where does Spring Webflux create a coroutine scope when using suspend functions?

This is a question about how Spring Webflux works under the hood.
When we build our Spring Webflux application in kotlin we can use suspend functions and interfaces like CoroutineCrudRepository to ‘get rid of’ abstractions such as Mono and Flux. However, we do not need to explicitly create a coroutine scope somewhere so it seems that Spring takes care of that. Where does Spring create this coroutine scope?
I would guess that a new scope is created when a request comes in and Spring then checks if the router or controller uses suspend functions. I cant find it anywhere in the code though.

Ktor equivalent of "Context" from project Reactor?

In project Reactor there is the concept of a Context which is a key value store that can be shared across components. We use it in some of our projects to manage the correlationId. API Reference: https://projectreactor.io/docs/core/release/api/reactor/util/context/Context.html
I am wondering in ktor is there a similar concept? I want a way to manage shared things such as a correlationId throughout the application that I can then pull from when making a client request?
Kotlin has a concept of a CoroutineContext which is similar to what you need - it's a map-like structure carried with every coroutine.
It's vaguely defined in the official documentation: here and here.
And this is how it for instance can be used for tracing: https://github.com/Shinigami072/OpenTracing-Kotlin-Coroutine-Integration/blob/master/coroutine-tracing-api-core/src/main/kotlin/ActiveSpan.kt

When to specify Dispatchers.xxx for coroutines in classes

I often create classes that have functions that contain a coroutine. It isn't always clear whether the function is being used by some component that is bound to the UI or whether it's doing background work that is more IO oriented. Here's an example:
fun myFunction() {
GlobalScope.launch {
// Do something
}
}
In this example, no Dispatcher.MAIN or Dispatchers.IO is specified. Is this the correct way to do this? Does the coroutine use the scope of whatever the calling client happens to be using? Should I only specify a dispatcher when I know definitively that I need a specific scope?
GlobalScope binds the lifecycle of the Coroutine to the lifecycle of the application itself.
Which means Coroutine started from this scope would continue to live until one of two things occur
Coroutine completes its job.
The Application itself is killed.
Using async or launch on the instance of GlobalScope is highly discouraged.
No Dispatcher.MAIN or Dispatchers.IO is specified. Is this the correct way to do this?
Yea, why not? If the work inside coroutine is not related to either UI or IO go for it.
Should I only specify a dispatcher when I know definitively that I
need a specific scope?
To answer this, let's first see the definition of launch from docs,
fun CoroutineScope.launch(
context: CoroutineContext = EmptyCoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> Unit ): Job (source)
The Dispatcher which we are talking about is a kind of CoroutineContext. As you can see in the definition if the CoroutineContext is not mentioned(which means we have not mentioned the Dispatcher too) it is by default set to EmptyCoroutineContext which internally uses Dispatchers.Default and this is what docs say about it,
The default CoroutineDispatcher that is used by all standard builders
like launch, async, etc if neither a dispatcher nor any other
ContinuationInterceptor is specified in their context.
It is backed by a shared pool of threads on JVM. By default, the
maximum number of threads used by this dispatcher is equal to the
number of CPU cores, but is at least two.
So even if you forget to mention the Dispatcher, Scheduler will pick any random available thread from the pool and hand it the Coroutine. But make sure that not to initiate any UI related work without mentioning the Dispatcher.
First of all, you must differentiate the scope from the context and dispatcher.
Coroutine scope is primarily about the lifecycle of the coroutine and deals with the concept of structured concurrency. It may have a default dispatcher, which would be the one logically associated with the object to which you tie the coroutine's lifecycle. For example, if you scope a coroutine to an Android activity, the default dispatcher will be UI.
Coroutine context refers to a dispatcher. The context should change during the coroutine's execution, as the logic inside requires it. Typically, you will use withContext to temporarily switch dispatchers in order to avoid blocking the UI thread. You will not typically launch the whole coroutine in the thread pool, unless all of it should run on a background thread (e.g., no UI interaction).
Second, the choice of dispatcher should be collocated with the code that requires a specific one. It should happen within the function that deals with a given concern, like making REST requests or DB operations. This once again reinforces the practice not to decide on dispatchers when launching the coroutine.
GlobalScope is an EmptyCoroutineScope and all coroutines launched with this scope are like demo threads. They cannot be canceled and remain active until their completion. I suggest implementing a specific scope e not using GlobalScope in order to control all the coroutines that are launched. The GlobalScope use the Dispatchers.Default as the default dispatcher and in your case you always create coroutines in the default dispatcher.

Whats the concept behind a CoroutineScope?

After reading the introduction and the javadoc of CoroutineScope I'm still a little confused what the idea behind a CoroutineScope is.
The first sentence of the doc "Defines a scope for new coroutines." is not clear to me: Why do my coroutines need a scope?
Also, why are standalone coroutine builders deprecated? Why is it better to do this:
fun CoroutineScope.produceSquares(): ReceiveChannel<Int> = produce {
for (x in 1..5) send(x * x)
}
instead of
fun produceSquares(): ReceiveChannel<Int> = produce { //no longer an extension function
for (x in 1..5) send(x * x)
}
You can still use global "standalone" coroutines by spawning them in GlobalScope:
GlobalScope.launch {
println("I'm running unstructured")
}
However, it's not recommended to do this since creating coroutines on a global scope is basically the same we did with good old threads. You create them but somehow need to keep track of a reference to later join/cancel them.
Using structured concurrency, that is nesting coroutines in their scopes, you will have a more maintainable system overall. For example, if you spawn a coroutine inside another one, you inherit the outer scope. This has multiple advantages. If you cancel the outer coroutine, the cancellation will be delegated to its inner coroutines. Also, you can be sure that the outer coroutine will not complete before all its children coroutines have done their work.
There's also a very good example shown in the documentation for CoroutineScope.
CoroutineScope should be implemented on entities with well-defined lifecycle that are responsible for launching children coroutines. Example of such entity on Android is Activity.
After all, the first version of your shown produceSquares methods is better as it is only executable if invoked in a CoroutineScope. That means you can run it inside any other coroutine:
launch {
produceSquares()
}
The coroutine created inside produceSquares inherits the scope of launch. You can be sure that launch does not complete before produceSquares. Also, if you cancelled launch, this would also effect produceSquares.
Furthermore, you can still create a globally running coroutine like this:
GlobalScope.produceSquares()
But, as mentioned, that's not the best option in most cases.
I'd also like to promote an article I wrote. There are some examples demonstrating what scopes mean: https://kotlinexpertise.com/kotlin-coroutines-concurrency/
It is related to the concept of structured concurrency, which defines a structure between coroutines.
On a more philosophical level, you rarely launch coroutines “globally”, like you do with threads. Coroutines are always related to some local scope in your application, which is an entity with a limited life-time, like a UI element. So, with structured concurrency we now require that launch is invoked in a CoroutineScope, which is an interface implemented by your life-time limited objects (like UI elements or their corresponding view models).
As an evident consequence of this concept: by cancelling the context of a scope, all it's subcoroutines will be canceled, too.

Kotlin 1.3: how to execute a block on a separate thread?

I've been reading up about concurrency in Kotlin and thought I started to understand it... Then I discovered that async() has been deprecated in 1.3 and I'm back to the start.
Here's what I'd like to do: create a thread (and it does have to be a thread rather than a managed pool, unfortunately), and then be able to execute async blocks on that thread, and return Deferred instances that will let me use .await().
What is the recommended way to do this in Kotlin?
1. Single-threaded coroutine dispatcher
Here's what I'd like to do: create a thread (and it does have to be a thread rather than a managed pool, unfortunately)
Starting a raw thread to handle your coroutines is an option only if you're prepared to dive deep and implement your own coroutine dispatcher for that case. Kotlin offers support for your requirement via a single-threaded executor service wrapped into a dispatcher. Note that this still leaves you with almost complete control over how you start the thread, if you use the overload that takes a thread factory:
val threadPool = Executors.newSingleThreadExecutor {
task -> Thread(task, "my-background-thread")
}.asCoroutineDispatcher()
2. async-await vs. withContext
and then be able to execute async blocks on that thread, and return Deferred instances that will let me use .await().
Make sure you actually need async-await, which means you need it for something else than
val result = async(singleThread) { blockingCal() }.await()
Use async-await only if you need to launch a background task, do some more stuff on the calling thread, and only then await() on it.
Most users new to coroutines latch onto this mechanism due to its familiarity from other languages and use it for plain sequential code like above, but avoiding the pitfall of blocking the UI thread. Kotlin has a "sequential by default" philosophy which means you should instead use
val result = withContext(singleThread) { blockingCall() }
This doesn't launch a new coroutine in the background thread, but transfers the execution of the current coroutine onto it and back when it's done.
3. Deprecated top-level async
Then I discovered that async() has been deprecated in 1.3
Spawning free-running background tasks is a generally unsound practice because it doesn't behave well in the case of errors or even just unusual patterns of execution. Your calling method may return or fail without awaiting on its result, but the background task will go on. If the application repeatedly re-enters the code that spawns the background task, your singleThread executor's queue will grow without bound. All these tasks will run without a purpose because their requestor is long gone.
This is why Kotlin has deprecated top-level coroutine builders and now you must explicitly qualify them with a coroutine scope whose lifetime you must define according to your use case. When the scope's lifetime runs out, it will automatically cancel all the coroutines spawned within it.
On the example of Android this would amount to binding the coroutine scope to the lifetime of an Activity, as explained in the KDoc of CoroutineScope.
Like it's stated with the message, it's deprecated in favor of calling async with an explicit scope like GlobalScope.async {} instead.
This is the actual implementation of the deprecated method as well.
By removing the top level async function, you'll not run into issues with implicit scopes or wrong imports.
Let me recommend this solution: Kotlin coroutines with returned value
It parallelizes tasks into 3 background threads (so called "triplets pool") but it's easy to change it to be single threaded as per your requirement by replacing tripletsPool with backgroundThread as below:
private val backgroundThread = ThreadPoolExecutor(1, 1, 5L, TimeUnit.SECONDS, LinkedBlockingQueue())