Well, a lot of questions about the + operator for context.
I can use commonPool + job(or coroutineContext) or job(or coroutineContext) + commonPool do the same thing and canceling a launch with calling cancel on job(or coroutineContext), however, when I use newSingleThreadContext, there's a difference between newSingleThreadContext + job(or coroutineContext) and job(or coroutineContext) + newSingleThreadContext . Only the first one can be canceled by job(or coroutineContext) like commonPool case.
Is it really not consistent of + operator? need some tips on this topic.
Have some codes which are ready for the combination of all these dispatchers or context.
fun logln(msg: String) = println("[${Thread.currentThread().name}: ] $msg")
fun combineContext() = launch(newSingleThreadContext("worker-parent")) {
logln("Evaluation the combination of contexts")
logln("echo parent")
val job = Job() //Only for fun, it can abort all launches and make child not child of parent.
launch( //CommonPool
newSingleThreadContext("worker-child 0") + coroutineContext //+ job //
) {
delay(3, TimeUnit.SECONDS)
launch( //CommonPool
newSingleThreadContext("worker-child 1") + coroutineContext //+ job
) {
delay(3, TimeUnit.SECONDS)
launch( //CommonPool
newSingleThreadContext("worker-child 2") + coroutineContext //+ job
) {
delay(3, TimeUnit.SECONDS)
logln("echo child 3")
}
logln("echo child 2")
}
logln("echo child 1")
}
//job.cancel()
//coroutineContext.cancel()
}
Coroutine context behaves like a map of context elements. You can run this code to get some intuition:
fun main(args: Array<String>) {
println(mapOf(1 to "A") + mapOf(2 to "B")) // {1=A, 2=B}
println(mapOf(1 to "A") + mapOf(1 to "B")) // {1=B}
println(mapOf(1 to "B") + mapOf(1 to "A")) // {1=A}
}
Does it help?
so, ok, might be a little improved. that means....
launch(a+b+c....) {...},
i.e The right ones will only overwrite the same or shared properties that the left ones also have, am I right?
Yes. Elements to the right of + overwrite elements with they same _key_ to the left. Just like with maps. Context is conceptually a map.
ok, got it.
The last Q: cancellation on coroutine.
launch(a+b+c....) {...},
because I've tried job+ newSingleThreadContext and newSingleThreadContext + job.
the job can cancel only at 2nd case, the 1.st case brings nothing, however, the job can cancel for case like CommonPool + job and job + CommonPool,
any magic ?
newSingleThreadContext = dispatcher + job.
@elizarov now, all in , got it, thx
Note, that the logic of newSingleThreadContext is being change in the last release. See #149 for details
@elizarov so well, this change can put down my confuse now.
coroutineContext + newSingleThreadContext("worker-child 0") //+ coroutineContext
works same putting parent left or right, it solves confuse and logic-natural like other cases.
Most helpful comment
https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/new-single-thread-context.html
newSingleThreadContext= dispatcher + job.