Conceptual question: I have a bunch of coroutines ...
# coroutines
w
Conceptual question: I have a bunch of coroutines that might at some point want to know, say, the latest USD-EUR conversion rate. My
getUsdEurRate()
function is expensive, so essentially what I want is: • Every consumer registers somewhere • When there is an active registration, the function gets kicked off and all the consumers suspend until we get a value back ◦ As other consumers may register while the function is running • No consumer should ever get a stale value My first approach was to use a 0-capacity synchronization channel, but based on the above thread, it sounds like channels don't really support both "no buffered values" and "multiple consumers get the same value". Is a flow the right approach here? Or something else?
j
SharedFlow for sure
k
MutableSharedFlow
s
A flow might be overkill, I'd be tempted to just say make a var that holds a Deferred. The first consumer to arrive initialises the var with an async job; subsequent consumers just await the already running job.
k
True, that's another possible option
Deferrable
using
async
, right? 🤔
r
Deferred will work for the first value but won't allow subsequent updates.
g
Deferred will work only for one value and may be less flexible in case of update, which you most probably need at some point (for example if you want to implement manual refresh of currency rate by user)
w
Thanks all!
e
If you decide to use flow you can do:
Copy code
flow { getUsdEurRate() }
  .shareIn(scope, SharingStarted.Lazily)
OR
Copy code
val shared = MutableSharedFlow()
shared.onSubscription { getUsdEurRate() }
j
Ideally with a flow the value would be streamed to callers over time