Cold and Hot Flows

Cold and Hot Flows

Table of contents

In this series of articles , we are discussing about Kotlin flows and in this article we will discuss about Cold and Hot Flows

Cold Flow

  • Flows created with flow builders are cold by default

Properties

  • Becomes active on terminal operators(like collect , first, last ....)

  • Becomes inactive when cancelling the collecting coroutine

  • They emit individual emissions to every collector

  • Emission and Collection are happening in same coroutines

suspend fun main(): Unit = coroutineScope {

    launch {
        println("Collector 1 in ${Thread.currentThread().name}")
        simpleFlow().collect { value ->
            println("Collecting from Collector 1 -> $value")
        }
    }

    launch {
        println("Collector 2 in ${Thread.currentThread().name}")
        simpleFlow().collect { value ->
            println("Collecting from Collector 2 -> $value")
        }
    }
}


private fun simpleFlow() = flow {
    println("Emission in ${Thread.currentThread().name}")
    repeat(3){
        kotlinx.coroutines.delay(250)
        println("Emitting $it")
        emit(it)
    }
}

/**
 * output
 * Collector 1 in DefaultDispatcher-worker-2
 * Collector 2 in DefaultDispatcher-worker-1
 * Emission in DefaultDispatcher-worker-2
 * Emission in DefaultDispatcher-worker-1
 * Emitting 0
 * Emitting 0
 * Collecting from Collector 1 -> 0
 * Collecting from Collector 2 -> 0
 * Emitting 1
 * Emitting 1
 * Collecting from Collector 2 -> 1
 * Collecting from Collector 1 -> 1
 * Emitting 2
 * Emitting 2
 * Collecting from Collector 2 -> 2
 * Collecting from Collector 1 -> 2
 */

In above code , we can observe the following

  • Emissions and collectors are running in same coroutine

  • Individual Emissions for every collectors

Code can be found inhttps://gist.github.com/vprabhu/69d912d7dfb8751badd26dff1d8eba1a

Hot Flow

  • are active regardless of existence of collectors

Properties

  • values that got emitted after we start collecting are the ones we will collect , it is possible to lose some emissions

  • stays active even when is no collectors

  • Emissions and collections are happening in different coroutines

Types of Hot Flow

1.Shared Flow

2.State Flow

suspend fun main(): Unit = coroutineScope {

    val sharedFlow = MutableSharedFlow<Int>()

    launch {
        println("Emitting in ${Thread.currentThread().name}")
        repeat(3) {
            kotlinx.coroutines.delay(250)
            println("Emitting $it")
            sharedFlow.emit(it)
        }
    }

    launch {
        println("Collector 1 in ${Thread.currentThread().name}")
        delay(550)
        sharedFlow.collect { value ->
            println("Collecting from Collector 1 -> $value")
        }
    }

    launch {
        println("Collector 2 in ${Thread.currentThread().name}")
        sharedFlow.collect { value ->
            println("Collecting from Collector 2 -> $value")
        }
    }
}

/**
 * output :
 * Emitting in DefaultDispatcher-worker-2
 * Collector 1 in DefaultDispatcher-worker-1
 * Collector 2 in DefaultDispatcher-worker-3
 * Emitting 0
 * Collecting from Collector 2 -> 0
 * Emitting 1
 * Collecting from Collector 2 -> 1
 * Emitting 2
 * Collecting from Collector 1 -> 2
 * Collecting from Collector 2 -> 2
 *
 *
 */

In above code , we can observe the following

  • Emission and Collectors are happening in different coroutines

  • we can see in output where Collector 2 is the only one which collects all emissions and Collector 1 has missed emissions

Code can be found in https://gist.github.com/vprabhu/30f210ce4f9e8a3b89b2b92416e53493

In the next article , we will discuss about State Flow and Shared Flow.

Please leave your comments to improve and discuss more

Happy and Enjoy coding