Just how lightweight are Coroutines Channels

I understand coroutines are usually referred as “lightweight” threads, but I was wondering just how lightweight are channels themselves.

I’m in the situation of communicating coroutines. The base is there’s a single event handler which then needs to forward the received event to one of the coroutines so that particular one can continue it’s execution. At a given time there may be hundred or thousands of coroutines waiting for their specific event (identified by a unique id) in order to continue.

I can see two approaches to solve the issue:

  1. Create a channel for each invocation on a mapOf(id, channel), then from the event handler, retreive the appropriate channel and forward the message to it, destroying and unregistering the channel afterwards. This will be constantly creating and destroying channels at a rate of, potentially, hundred per second.
  2. Create a single broadcast channel and subscribe all coroutines to it. Forward the event to ALL coroutines and have each of them receive the event and check whether it belongs to them. This implies a single channel but all coroutines need to activate for each message in order to verify whether it belongs to them, potentially resulting on unsuspending and suspending at a rate of hundred of times per second.

Option 2 doesn’t feel like a viable solution to me as it just involves to many unrequired activations for the coroutines.

Option 1 should work fine as long as creating and destroying channels is a lighweight and fast operation.

Any advise as to whether Option1 is feasible or if there’s a better “Option 3” that I haven’t considered.

Note: In my current scenario, the coroutine executes a synchronous network request and then needs to wait for an asynchronous response that will be received in a different thread by a different handler. The idea is the coroutine will execute the request, suspend until asynchronous response is received and then resume and return the received response.

As the docs mention, Channel is just a threadsafe list so you are allocating thousands of lists and you are really just bound by memory.

CompletableDeferred is also an option if only dealing with one item.