Skip to content

Channel Types

Devrath edited this page Dec 27, 2023 · 15 revisions

Types of Channels

  • Buffered
  • Conflated
  • Rendezvous
  • Unlimited

Channel Type --> Buffered

Observation

  • You can observe that we have given the capacity = 2 for the produce operator.
  • So elements sent are a max of 2 elements.
  • In the receive you can observe once the earlier 2 elements are received. Then one element is received as the one element is sent by the producer, So until then the second coroutine is suspended.
  • Only when one element is received is that space available for the channel buffer to send the data.
  • Value 2 I passed below is configurable.

code

    private var receiveBufferChannel : ReceiveChannel<Countries> = Channel()

    fun usingBuffered() {
        // Co-Routine - 1
        viewModelScope.launch {

            // We are limiting the buffer capacity to 2
            receiveBufferChannel = produce(capacity = 2) {
                    println("Send Action : ----> USA")
                    send(Countries.USA)
                    println("Send Action : ----> Russia")
                    send(Countries.Russia)
                    println("Send Action : ----> India")
                    send(Countries.India)
                    println("Send Action : ----> France")
                    send(Countries.France)
                    println("Send Action : ----> Spain")
                    send(Countries.Spain)
                    println("Send Action : ----> Germany")
                    send(Countries.Germany)
                    println("Send Action : ----> Italy")
                    send(Countries.Italy)
            }

        }

        // Co-Routine - 2
        viewModelScope.launch {
            receiveBufferChannel.consumeEach { countries ->
                println("Receive Action : ----> $countries")
                println("---------------------------------")
                delay(3000)
            }
        }
    }

    enum class Countries { USA , Russia , India , France , Spain , Germany , Italy }

out-put

Send Action : ----> USA
Send Action : ----> Russia
Send Action : ----> India
Receive Action : ----> USA
---------------------------------
Send Action : ----> France
Send Action : ----> Spain
Receive Action : ----> Russia
---------------------------------
Send Action : ----> Germany
Receive Action : ----> India
---------------------------------
Send Action : ----> Italy
Receive Action : ----> France
---------------------------------
Receive Action : ----> Spain
---------------------------------
Receive Action : ----> Germany
---------------------------------
Receive Action : ----> Italy
---------------------------------

Channel Type --> Conflated

  • Here adding CONFLATED to the buffer size of produce indicates that only the latest one is received
  • Here the capacity is just 1

Observation

  • Here only the latest value is received no matter how many emissions happen, While others are dropped

code

    private var receiveConflatedChannel : ReceiveChannel<Birds> = Channel()

    fun usingConflated() {
        // Co-Routine - 1
        viewModelScope.launch {

            receiveConflatedChannel = produce(capacity = CONFLATED) {
                send(Birds.Eagle)
                send(Birds.Peacock)
                send(Birds.Robin)
                send(Birds.Ostrich)
                send(Birds.Pigeon)
                send(Birds.Kingfisher)
                send(Birds.Dodo)
            }

        }

        // Co-Routine - 2
        viewModelScope.launch {
            receiveConflatedChannel.consumeEach { birds ->
                println("BIRD : ----> $birds")
            }
        }
    }

    enum class Birds { Eagle , Peacock , Robin , Ostrich , Pigeon , Kingfisher , Dodo }

out-put

BIRD : ----> Dodo

Channel Type --> Rendezvous

  • If you do not specify any type, By default it is Rendezvous
  • Here on the receiver co-routine if it is not triggered the same number of times as the sender, then the co-routines remain suspended
  • That is because a few items are sent to the channel but some are not received on the receiver coroutine, Thus channel is not closed.

Observation

  • Observe that only these elements are printed since we are receiving only 3 elements then the receiver co-routine is suspended.
  • Also point to note when you are sending some elements in between some elements get received as well but in the UNLIMITED buffer size all are sent once and elements start to get received on the receiver.

code

    private var receiveRendezvousChannel : ReceiveChannel<Cars> = Channel()

    fun usingRendezvous() {
        // Co-Routine - 1
        viewModelScope.launch {

            receiveRendezvousChannel = produce() {
                println("SENT : ----> ${Cars.Maruthi}")
                send(Cars.Maruthi)
                println("SENT : ----> ${Cars.BMW}")
                send(Cars.BMW)
                println("SENT : ----> ${Cars.Tesla}")
                send(Cars.Tesla)
                println("SENT : ----> ${Cars.Byd}")
                send(Cars.Byd)
                println("SENT : ----> ${Cars.TATA}")
                send(Cars.TATA)
                println("SENT : ----> ${Cars.Ferrari}")
                send(Cars.Ferrari)
                println("SENT : ----> ${Cars.Porshe}")
                send(Cars.Porshe)
            }

        }

        // Co-Routine - 2
        viewModelScope.launch {
            println("CAR : ----> ${receiveConflatedChannel.receive()}")
            println("CAR : ----> ${receiveConflatedChannel.receive()}")
            println("CAR : ----> ${receiveConflatedChannel.receive()}")
        }
    }

    enum class Cars { Maruthi , BMW , Tesla , Byd , TATA , Ferrari , Porshe }

out-put

SENT : ----> Maruthi
CAR : ----> Maruthi
SENT : ----> BMW
SENT : ----> Tesla
CAR : ----> BMW
CAR : ----> Tesla
SENT : ----> Byd

Channel Type --> Unlimited

  • Here as the name suggests the channel size is unlimited but might cause out-of-memory if the size is not available
  • Also it differed from default one Rendezvous as shown in observation.

Observation

  • Note that in output only 3 elements are received.
  • Also see all are sent, Only then do elements start to get received.

code

    private var receiveUnlimitedChannel : ReceiveChannel<Cars> = Channel()

    fun usingUnlimited() {
        // Co-Routine - 1
        viewModelScope.launch {

            receiveUnlimitedChannel = produce {
                println("SENT : ----> ${Cars.Maruthi}")
                send(Cars.Maruthi)
                println("SENT : ----> ${Cars.BMW}")
                send(Cars.BMW)
                println("SENT : ----> ${Cars.Tesla}")
                send(Cars.Tesla)
                println("SENT : ----> ${Cars.Byd}")
                send(Cars.Byd)
                println("SENT : ----> ${Cars.TATA}")
                send(Cars.TATA)
                println("SENT : ----> ${Cars.Ferrari}")
                send(Cars.Ferrari)
                println("SENT : ----> ${Cars.Porshe}")
                send(Cars.Porshe)
            }

        }

        // Co-Routine - 2
        viewModelScope.launch {
            println("CAR : ----> ${receiveUnlimitedChannel.receive()}")
            println("CAR : ----> ${receiveUnlimitedChannel.receive()}")
            println("CAR : ----> ${receiveUnlimitedChannel.receive()}")
        }
    }

    enum class Cars { Maruthi , BMW , Tesla , Byd , TATA , Ferrari , Porshe }

out-put

SENT : ----> Maruthi
SENT : ----> BMW
SENT : ----> Tesla
SENT : ----> Byd
SENT : ----> TATA
SENT : ----> Ferrari
SENT : ----> Porshe
CAR : ----> Maruthi
CAR : ----> BMW
CAR : ----> Tesla
Clone this wiki locally