Real World Example

Uber-style Ride Dispatch

Ride requests arrive in bursts. A bounded channel works as a queue, and a fixed pool of dispatcher coroutines takes requests one by one and assigns the nearest free driver. If the queue is full, new requests wait (back-pressure) instead of overloading the system.

riders ──trySend──► Channel(capacity = 10) ──► dispatcher 1 ┐
                                           └──► dispatcher 2 ┴─► assignments

Code

Example

import kotlinx.coroutines.*
import kotlinx.coroutines.channels.*
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import kotlin.math.abs

data class RideRequest(val rider: String, val km: Int)
data class Driver(val name: String, val km: Int)

fun main() = runBlocking {
    val requests = Channel<RideRequest>(capacity = 10)
    val freeDrivers = mutableListOf(Driver("Ramesh", 2), Driver("Suresh", 9), Driver("Anil", 5), Driver("Imran", 14))
    val lock = Mutex()
    val assignments = mutableListOf<String>()

    val dispatchers = List(2) {
        launch {
            for (req in requests) {
                delay(20)    // map lookup
                lock.withLock {
                    val driver = freeDrivers.minByOrNull { abs(it.km - req.km) }
                    if (driver == null) {
                        assignments += "${req.rider}: no driver available"
                    } else {
                        freeDrivers.remove(driver)
                        assignments += "${req.rider} -> ${driver.name} (${abs(driver.km - req.km)} km away)"
                    }
                }
            }
        }
    }

    listOf(RideRequest("Kavya", 3), RideRequest("Arjun", 10), RideRequest("Neha", 6),
        RideRequest("Rohit", 13), RideRequest("Divya", 1)).forEach { requests.send(it) }
    requests.close()
    dispatchers.joinAll()
    assignments.forEach(::println)
}

Output

Kavya -> Ramesh (1 km away)
Arjun -> Suresh (1 km away)
Neha -> Anil (1 km away)
Rohit -> Imran (1 km away)
Divya: no driver available

Tip: Mutex is the coroutine version of a lock: withLock suspends instead of blocking a thread while it waits.