I have a question about Kotlin flow buffer capacity. The following code:
import kotlinx.coroutines.flow.*
suspend fun main() = coroutineScope {
flow {
for (i in 1..3) {
println("Emiting $i")
emit(i)
}
}.buffer(0)
.collect {
value ->
delay(100)
println("Consuming $value")
}
}
generates the following output:
Emiting 1
Emiting 2
Consuming 1
Emiting 3
Consuming 2
Consuming 3
If I remove the buffer, the result is:
Emiting 1
Consuming 1
Emiting 2
Consuming 2
Emiting 3
Consuming 3
Shall I assume that when the capacity is 0 means that is actually 1?
No, the capacity is actually 0. It just looks like you are buffering an element because the collect is first consuming an element, and then delays for 100ms. That allows the flow to emit another element in the meanwhile.
The buffer function actually creates a second coroutine that allows the flow and collect functions to execute concurrently. Without the call to buffer, each element must be done with the collect before flow can continue with the next element, because both functions are executed by the same coroutine.
Let's step through your code to figure out how it happens:
Emitting 1, emits 1, and suspends.1, then starts the delay for 100ms.1 was consumed, delays for another 1ms, prints Emitting 2, emits 2, then suspends.Consuming 1, then consumes 2 and delays for another 100ms.2 was consumed, delays for another 1ms, prints Emitting 3, emits 3, then suspends.Consuming 2, then consumes 3 and delays for another 100ms.Consuming 3, then finishes collecting.You can read more about buffer here: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/buffer.html
Not really, it's 0. The buffer(0) method uses a channel under the hood, and size 0 effectively makes the channel an unbuffered channel. The flow and consumer both need to be ready to emit/consume:
Unbuffered channels transfer elements when sender and receiver meet each other (aka rendezvous). buffered-channels
delay 100delay 100delay 100When you remove the buffer(0), the situation is a bit different. there is no channel involved. The flow is a "cold-stream", i.e. it kind of waits for the consumer to pull next items:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With