arnaud.giuliani
03/20/2019, 3:08 PMstructured concurrency
. If I understand, the thing is to ensure that we reuse a proper CoroutineScope
instead of launching coroutines in the `Global`f scope. Then here is my question. I have 2 components: A
& B
. My component A
initiate a coroutine scope and I can run functions against that. How do I share/propagate it to my component B
on which I want to call functions.
class A {
val coroutineContext: CoroutineContext ...
}
class B {
fun myFunction(){
// run with A.coroutineContext?
}
}
Do we have to pass the coroutineContext
as an argument to any call of B
?bdawg.io
03/20/2019, 4:04 PMA
implement CoroutineScope
and then inject an instance of A
into B
class A : CoroutineScope {
override val coroutineContext: CoroutineContext ...
}
class B(private val a: A) {
fun myFunction() {
a.launch { ... }
}
}
bdawg.io
03/20/2019, 4:05 PMgildor
03/20/2019, 4:06 PMarnaud.giuliani
03/20/2019, 4:07 PMarnaud.giuliani
03/20/2019, 4:07 PMarnaud.giuliani
03/20/2019, 4:07 PMarnaud.giuliani
03/20/2019, 4:07 PMarnaud.giuliani
03/20/2019, 4:08 PMgildor
03/20/2019, 4:11 PMarnaud.giuliani
03/20/2019, 4:11 PMarnaud.giuliani
03/20/2019, 4:11 PMgildor
03/20/2019, 4:11 PMarnaud.giuliani
03/20/2019, 4:12 PMgildor
03/20/2019, 4:12 PMarnaud.giuliani
03/20/2019, 4:12 PMarnaud.giuliani
03/20/2019, 4:14 PMarnaud.giuliani
03/20/2019, 4:14 PMghedeon
03/20/2019, 4:14 PMwithContext
. No need to pass CoroutineScope.gildor
03/20/2019, 4:14 PMgildor
03/20/2019, 4:15 PMarnaud.giuliani
03/20/2019, 4:16 PMarnaud.giuliani
03/20/2019, 4:16 PMgildor
03/20/2019, 4:16 PMarnaud.giuliani
03/20/2019, 4:16 PMA
and subcomponents called from A
are suspending functionsghedeon
03/20/2019, 4:16 PMarnaud.giuliani
03/20/2019, 4:16 PMA
start a coroutines in backgroundarnaud.giuliani
03/20/2019, 4:17 PMgildor
03/20/2019, 4:17 PMarnaud.giuliani
03/20/2019, 4:18 PMgildor
03/20/2019, 4:18 PMgildor
03/20/2019, 4:18 PMgildor
03/20/2019, 4:19 PMghedeon
03/20/2019, 4:19 PMoverride val coroutineContext: CoroutineContext = job + Dispatchers.Main
In B:
suspend fun foo(){
withContext(<http://Dispatchers.IO|Dispatchers.IO>){ some work }
}
For channels you'd need to pass the scope.arnaud.giuliani
03/20/2019, 4:19 PMgildor
03/20/2019, 4:19 PMarnaud.giuliani
03/20/2019, 4:20 PMgildor
03/20/2019, 4:20 PMgildor
03/20/2019, 4:20 PMarnaud.giuliani
03/20/2019, 4:20 PMarnaud.giuliani
03/20/2019, 4:20 PMgildor
03/20/2019, 4:20 PMarnaud.giuliani
03/20/2019, 4:26 PMproduce
directly from a suspending functionarnaud.giuliani
03/20/2019, 4:26 PMarnaud.giuliani
03/20/2019, 4:29 PMclass A(val b : B) {
val rootJob = Job()
val coroutineContext = rootJob + <http://Dispatchers.dispatcherConfiguration.io|Dispatchers.dispatcherConfiguration.io>()
fun runMe() = coroutineContext.launch {
b.runMyChannel().consumeEach { myBooleanValue ->
// have incoming data
}
}
}
class B {
suspend fun runMyChannel() = Channel<Boolean>{
val channel = Channel<Boolean>()
Global.async {
// send a boolean value in a async way
val myBooleanValue = true
channel.send(myBooleanValue)
}
return channel
}
}
arnaud.giuliani
03/20/2019, 4:31 PMGlobal.async
to send data in a async way?gildor
03/20/2019, 4:32 PMI can’t useYes, this is what I mentioned above, you need some scopedirectly from a suspending functionproduce
arnaud.giuliani
03/20/2019, 4:33 PMgildor
03/20/2019, 4:33 PMarnaud.giuliani
03/20/2019, 4:34 PMgildor
03/20/2019, 4:34 PMarnaud.giuliani
03/20/2019, 4:34 PMB
have its own scope?arnaud.giuliani
03/20/2019, 4:35 PMB
to ensure that if we cancel A
we cancel cal to B
gildor
03/20/2019, 4:35 PMarnaud.giuliani
03/20/2019, 4:35 PMr4zzz4k
03/20/2019, 4:36 PMonBindViewHolder
of RecyclerView.Adapter
, I have to pass `Fragment`s scope to the adapter explicitly, right?arnaud.giuliani
03/20/2019, 4:36 PMarnaud.giuliani
03/20/2019, 4:36 PMarnaud.giuliani
03/20/2019, 4:36 PMB
I have old async API with callbacksarnaud.giuliani
03/20/2019, 4:37 PMr4zzz4k
03/20/2019, 4:37 PMclass MyAdapter(coroutineScole: CoroutineScope): RecyclerView.Adapter<...>(), CoroutineScope by coroutineScope {
should do?gildor
03/20/2019, 4:37 PMarnaud.giuliani
03/20/2019, 4:38 PMr4zzz4k
03/20/2019, 4:38 PMgildor
03/20/2019, 4:38 PMarnaud.giuliani
03/20/2019, 4:39 PMarnaud.giuliani
03/20/2019, 4:39 PMarnaud.giuliani
03/20/2019, 4:39 PMarnaud.giuliani
03/20/2019, 4:40 PMgildor
03/20/2019, 4:40 PMIt's not incorrect, it's just explicit about it's context. IIRCI'm not sure that it is the same tho, maybe, but it's not enough context to be sure
arnaud.giuliani
03/20/2019, 4:41 PMuser.getIdToken()
.addOnCompleteListener { task ->
// send my data here, but in other thread
}
gildor
03/20/2019, 4:41 PMarnaud.giuliani
03/20/2019, 4:42 PMgildor
03/20/2019, 4:42 PMgildor
03/20/2019, 4:42 PMarnaud.giuliani
03/20/2019, 4:42 PMr4zzz4k
03/20/2019, 4:42 PMarnaud.giuliani
03/20/2019, 4:43 PMgildor
03/20/2019, 4:43 PMr4zzz4k
03/20/2019, 4:44 PMgildor
03/20/2019, 4:44 PMarnaud.giuliani
03/20/2019, 4:45 PMarnaud.giuliani
03/20/2019, 4:46 PMarnaud.giuliani
03/20/2019, 4:46 PMkotlinx-coroutines-play-services
will clearly help 👍arnaud.giuliani
03/20/2019, 4:46 PMarnaud.giuliani
03/20/2019, 4:47 PMWrapping callbacks
also 👍r4zzz4k
03/20/2019, 4:48 PMgildor
03/20/2019, 4:50 PMr4zzz4k
03/20/2019, 4:54 PMChannel
itself or provides a channel where it emits events observed in upstream (and vice versa).gildor
03/20/2019, 4:59 PMgildor
03/20/2019, 5:00 PMarnaud.giuliani
03/20/2019, 5:02 PMDico
03/20/2019, 6:26 PMclass B {
fun CoroutineScope.runMyChannel() = Channel<Boolean>().also { launch { it.send(true) } }
gildor
03/20/2019, 11:35 PMbdawg.io
03/21/2019, 3:25 AMproduce
closes the channel when the produce
coroutine returnsgildor
03/21/2019, 3:35 AMDico
03/21/2019, 4:04 AMgildor
03/21/2019, 4:05 AMDico
03/21/2019, 4:05 AMDico
03/21/2019, 4:06 AMoffer
😂 no CoroutineScope neededAntanas A.
03/21/2019, 8:50 AMAntanas A.
03/21/2019, 8:58 AMAntanas A.
03/21/2019, 8:59 AMAntanas A.
03/21/2019, 9:03 AMAntanas A.
03/21/2019, 9:05 AMarnaud.giuliani
03/21/2019, 9:19 AMAntanas A.
03/21/2019, 9:22 AMgildor
03/21/2019, 9:23 AMif A’s object scope will be cancelled all invocations deep inside call graph of withContext launch won’t be cancelled (they are non-cancellable by defaultThis is incorrect
gildor
03/21/2019, 9:24 AMAntanas A.
03/21/2019, 9:24 AMgildor
03/21/2019, 9:24 AMgildor
03/21/2019, 9:25 AMgildor
03/21/2019, 9:25 AMgildor
03/21/2019, 9:25 AMAntanas A.
03/21/2019, 9:25 AMAntanas A.
03/21/2019, 9:26 AMAntanas A.
03/21/2019, 9:27 AMAntanas A.
03/21/2019, 9:27 AMgildor
03/21/2019, 9:27 AMa Job which was started by withContext is not cancelled by thatwithContext doesn’t start any Jobs, I don’t understand what you mean
Antanas A.
03/21/2019, 9:29 AMAntanas A.
03/21/2019, 9:30 AMAntanas A.
03/21/2019, 9:31 AMAntanas A.
03/21/2019, 9:31 AMgildor
03/21/2019, 9:34 AMgildor
03/21/2019, 9:34 AMgildor
03/21/2019, 9:36 AMAntanas A.
03/21/2019, 9:36 AMAntanas A.
03/21/2019, 9:36 AMAntanas A.
03/21/2019, 9:36 AMAntanas A.
03/21/2019, 9:36 AMAntanas A.
03/21/2019, 9:36 AMAntanas A.
03/21/2019, 9:37 AMgildor
03/21/2019, 9:37 AMAntanas A.
03/21/2019, 9:37 AMgildor
03/21/2019, 9:37 AMgildor
03/21/2019, 9:37 AMAntanas A.
03/21/2019, 9:38 AMgildor
03/21/2019, 9:38 AMgildor
03/21/2019, 9:38 AMAntanas A.
03/21/2019, 9:38 AMAntanas A.
03/21/2019, 9:39 AMAntanas A.
03/21/2019, 9:39 AMAntanas A.
03/21/2019, 9:39 AMAntanas A.
03/21/2019, 9:40 AMgildor
03/21/2019, 9:40 AMAntanas A.
03/21/2019, 9:40 AMgildor
03/21/2019, 9:40 AMimplementing coroutineContext of CoroutineScope without explicit job is unknown behaviourWhat do you mean?
gildor
03/21/2019, 9:41 AMAntanas A.
03/21/2019, 9:41 AMAntanas A.
03/21/2019, 9:41 AMgildor
03/21/2019, 9:42 AMgildor
03/21/2019, 9:42 AMAntanas A.
03/21/2019, 9:42 AMgildor
03/21/2019, 9:42 AMAntanas A.
03/21/2019, 9:42 AMgildor
03/21/2019, 9:42 AMAntanas A.
03/21/2019, 9:43 AMAntanas A.
03/21/2019, 9:43 AMAntanas A.
03/21/2019, 9:44 AMAntanas A.
03/21/2019, 9:44 AMAntanas A.
03/21/2019, 9:45 AMgildor
03/21/2019, 9:45 AMwithContext(this.coroutineScope)
Antanas A.
03/21/2019, 9:45 AMAntanas A.
03/21/2019, 9:45 AMAntanas A.
03/21/2019, 9:46 AMAntanas A.
03/21/2019, 9:46 AMAntanas A.
03/21/2019, 9:46 AMgildor
03/21/2019, 9:46 AMwithContext(MyDispatcher)
gildor
03/21/2019, 9:47 AMAntanas A.
03/21/2019, 9:47 AMAntanas A.
03/21/2019, 9:47 AMAntanas A.
03/21/2019, 9:47 AMAntanas A.
03/21/2019, 9:47 AMAntanas A.
03/21/2019, 9:48 AMgildor
03/21/2019, 9:48 AMAntanas A.
03/21/2019, 9:48 AMAntanas A.
03/21/2019, 9:48 AMgildor
03/21/2019, 9:49 AMAntanas A.
03/21/2019, 9:49 AMgildor
03/21/2019, 9:49 AMAntanas A.
03/21/2019, 9:49 AMgildor
03/21/2019, 9:49 AMgildor
03/21/2019, 9:49 AMgildor
03/21/2019, 9:50 AMAntanas A.
03/21/2019, 9:50 AMAntanas A.
03/21/2019, 9:51 AMgildor
03/21/2019, 9:51 AMgildor
03/21/2019, 9:51 AMAntanas A.
03/21/2019, 9:51 AMgildor
03/21/2019, 9:52 AMbut the pratice is if you are implementing CoroutineScope interface you should define job object otherwise it won’t be possible to control scopeDepending on how you do this
gildor
03/21/2019, 9:52 AMCoroutineScope()
or MainScope
builders job will be created for your, no need to create it explictlyAntanas A.
03/21/2019, 9:52 AMAntanas A.
03/21/2019, 9:52 AMgildor
03/21/2019, 9:53 AMAntanas A.
03/21/2019, 9:53 AMgildor
03/21/2019, 9:53 AMAntanas A.
03/21/2019, 9:53 AMgildor
03/21/2019, 9:53 AMwithContext(this.coroutineContext)
just wrong by definition IMOgildor
03/21/2019, 9:54 AMAntanas A.
03/21/2019, 9:54 AMgildor
03/21/2019, 9:54 AMAntanas A.
03/21/2019, 9:54 AMAntanas A.
03/21/2019, 9:54 AMAntanas A.
03/21/2019, 9:54 AMgildor
03/21/2019, 9:54 AMAntanas A.
03/21/2019, 9:55 AMgildor
03/21/2019, 9:55 AMwithContext(this.coroutineContext) {
someSuspendCall()
}
and
someSuspendCall()
Is just the sameAntanas A.
03/21/2019, 9:55 AMAntanas A.
03/21/2019, 9:55 AMAntanas A.
03/21/2019, 9:56 AMgildor
03/21/2019, 9:56 AMcoroutineScope{}
instead of withContext(this.coroutineContext
Antanas A.
03/21/2019, 9:56 AMgildor
03/21/2019, 9:56 AMAntanas A.
03/21/2019, 9:56 AMgildor
03/21/2019, 9:56 AMgildor
03/21/2019, 9:56 AMAntanas A.
03/21/2019, 9:56 AMAntanas A.
03/21/2019, 9:57 AMgildor
03/21/2019, 9:57 AMAntanas A.
03/21/2019, 9:57 AMgildor
03/21/2019, 9:57 AMAntanas A.
03/21/2019, 9:57 AMgildor
03/21/2019, 9:57 AMAntanas A.
03/21/2019, 9:57 AMAntanas A.
03/21/2019, 9:58 AMAntanas A.
03/21/2019, 9:58 AMAntanas A.
03/21/2019, 9:58 AMgildor
03/21/2019, 9:58 AMAntanas A.
03/21/2019, 9:58 AMgildor
03/21/2019, 9:58 AMgildor
03/21/2019, 9:58 AMthis.coroutineContext[CoroutineDispather]
Antanas A.
03/21/2019, 9:58 AMgildor
03/21/2019, 9:58 AMAntanas A.
03/21/2019, 9:59 AMgildor
03/21/2019, 9:59 AMbut also I want somehow to cancel all suspended download() calls in system with another background operation which destroys and cancels downloaderI belive this is use case for Actor
Antanas A.
03/21/2019, 9:59 AMAntanas A.
03/21/2019, 10:00 AMAntanas A.
03/21/2019, 10:00 AMAntanas A.
03/21/2019, 10:01 AMgildor
03/21/2019, 10:01 AMAntanas A.
03/21/2019, 10:01 AMAntanas A.
03/21/2019, 10:01 AMgildor
03/21/2019, 10:01 AMgildor
03/21/2019, 10:01 AMgildor
03/21/2019, 10:01 AMAntanas A.
03/21/2019, 10:01 AMAntanas A.
03/21/2019, 10:02 AMgildor
03/21/2019, 10:02 AMAntanas A.
03/21/2019, 10:02 AMAntanas A.
03/21/2019, 10:03 AMAntanas A.
03/21/2019, 10:04 AMAntanas A.
03/21/2019, 10:04 AMAntanas A.
03/21/2019, 10:04 AMAntanas A.
03/21/2019, 10:04 AMgildor
03/21/2019, 10:05 AMAntanas A.
03/21/2019, 10:05 AMAntanas A.
03/21/2019, 10:05 AMAntanas A.
03/21/2019, 10:05 AMAntanas A.
03/21/2019, 10:06 AMAntanas A.
03/21/2019, 10:06 AMgildor
03/21/2019, 10:06 AMgildor
03/21/2019, 10:06 AMAntanas A.
03/21/2019, 10:06 AMgildor
03/21/2019, 10:07 AMAntanas A.
03/21/2019, 10:07 AMAntanas A.
03/21/2019, 10:07 AMgildor
03/21/2019, 10:08 AMAntanas A.
03/21/2019, 10:08 AMAntanas A.
03/21/2019, 10:09 AMAntanas A.
03/21/2019, 10:09 AMgildor
03/21/2019, 10:09 AMgildor
03/21/2019, 10:09 AMAntanas A.
03/21/2019, 10:09 AMAntanas A.
03/21/2019, 10:10 AMAntanas A.
03/21/2019, 10:10 AMAntanas A.
03/21/2019, 10:10 AMAntanas A.
03/21/2019, 10:11 AMAntanas A.
03/21/2019, 10:11 AMAntanas A.
03/21/2019, 10:11 AMAntanas A.
03/21/2019, 10:12 AMAntanas A.
03/21/2019, 10:13 AMAntanas A.
03/21/2019, 10:13 AMAntanas A.
03/21/2019, 10:14 AMAntanas A.
03/21/2019, 10:15 AMDico
03/21/2019, 1:19 PMDico
03/21/2019, 1:19 PMDico
03/21/2019, 1:20 PMwithScope
functionAntanas A.
03/21/2019, 2:00 PMDico
03/21/2019, 2:02 PMAntanas A.
03/21/2019, 2:03 PMDico
03/21/2019, 2:03 PMAntanas A.
03/21/2019, 2:04 PMAntanas A.
03/21/2019, 2:04 PMgildor
03/21/2019, 2:04 PMAntanas A.
03/21/2019, 2:04 PMAntanas A.
03/21/2019, 2:04 PMAntanas A.
03/21/2019, 2:05 PMAntanas A.
03/21/2019, 2:06 PMAntanas A.
03/21/2019, 2:06 PMAntanas A.
03/21/2019, 2:07 PMAntanas A.
03/21/2019, 2:08 PMAntanas A.
03/21/2019, 2:09 PM