Need some suggestions about events with coroutines and flows

In my project, some events can happen that callers need to be able to handle. One example would be an event that a device was added to the system, and the new device’s ID is communicated when that event occurs. The classic approach would be to either have some sort of onNewDevice function for installing a callback that is invoked when a new device is added (and that callback gets passed the device’s ID), or perhaps some “startEvents” function with one of the arguments being such a callback.

However, I figure that if I am already using coroutines, then there’s gotta be a nicer way to do that. I did stumble upon callbackFlow, but this is not really what I need I think - if I got this correctly, callbackFlow is intended to integrate existing callback-based APIs as flows.

So, how would you design an API to allow for notifying the user about a newly added device?

The one idea I had was to add a SharedFlow that transmits an Event structure that contains details about said event. However, with this flow, events can get lost if the replay cache gets full. I’d rather retain the backpressure and block, since losing events would be bad.

Another idea would be a Channel that transmits Event structures.

What would you do?

The listener API is simple, sufficient, and well-understood. There’s no reason to provide anything more complicated.

If the caller wants to, it can build any sort of asynchronous coroutine-based receiver on top of the listener API. If you find that the standard library doesn’t make whatever you want easy, then you build a reusable class to implement what you want on top of any listener API, instead of pushing complex requirements into the observable implementations.

Right. Well, I’m still rather new to Kotlin, and it was my impression that using callbacks is not really idiomatic. That’s my reason for asking. But if it is perfectly fine, then I’ll stick to those.