https://kotlinlang.org logo
#coroutines
Title
# coroutines
t

Thiyagu

01/03/2020, 12:56 PM
how does scope works in this gist? https://gist.github.com/thiyagu06/549b03512818eac42c123c4bd0456003#file-producerconsumer-kt-L45 .. Both
producerContext
and
consumerContext
will have same
CoroutineScope
?does
flowScope.cancel()
make both coroutines context not to accept any more task in it?
t

tseisel

01/03/2020, 1:20 PM
producerContext
and
consumerContext
are 2 independent contexts : one is backed by one thread, the other has a pool of 2 threads. When collecting from the flow, the code from
channelFlow
will be executed on the producer thread, and each element is notified on one of the consumer threads. Cancelling the
flowScope
results in : 1. Cancelling the consumer coroutine (the one started by
launchIn
) 2. Cancel collection of the flow, and therefore the block in
awaitClose
it called on the producer thread.
t

Thiyagu

01/03/2020, 1:26 PM
Thanks for the explanation. I understand that
flowScope.cancel()
is enough stop the flow and both coroutineContext will be stopped. both my context will be having the same scope?
t

tseisel

01/03/2020, 1:55 PM
Some vocabulary here : A
Job
is an unit of work that has a lifecycle : started, stopped, cancelled. A
CoroutineDispatcher
describes how coroutines are executed and resumed. It abstracts threads away. A
CoroutineContext
is the sum of multiple properties. `Job`s and `CoroutineDispatcher`s may be part of a
CoroutineContext
. A
CoroutineScope
is the primitive for structured concurrency. It simply wraps a
CoroutineContext
, and cancelling a scope indirectly cancels jobs that are part of its context. From those definitions, we deduce that : • being based on `CoroutineDispatcher`s, both
producerContext
and
consumerContext
will not stop, their thread pool will still be allocated. • Because the producer coroutine in
channelFlow
is launched in the scope of its
ProducerScope
, it is automatically cancelled when the flow collection is cancelled (you don't need to manually cancel the job in
awaitClose
)
👍 1
Then yes, cancellation of the coroutine that called
collect
(or
launchIn
in this case) will cancel any upstream operations, including the producer.
Note : you can simplify the
channelFlow
block by replacing it with the following :
Copy code
flow {
    while(true) {
        emit(Random.nextInt(1000)
        delay(100)
    }
}.buffer()
t

Thiyagu

01/03/2020, 2:36 PM
Hey again thanks for the nice explanation of each concept. I update the gist based on your inputs. https://gist.github.com/thiyagu06/549b03512818eac42c123c4bd0456003. The reason i'm using using channelFlow is, I will replace the random number generation with http request.
Basically, I tried to achieve the below things. This will be independent JVM process which will run in background. When I stop the background thread, all coroutines must stopped properly. 1. poll indefinitely http endpoint and get the data in batches(say 10 per batch) 2. do some async process and store it in DB 3. acknowledge that received data is processed successfully.(call http endpoint)
5 Views