kotlinx.coroutines icon indicating copy to clipboard operation
kotlinx.coroutines copied to clipboard

Add a .throttle(Duration) Flow extension that prevents short burst of emission in a time frame

Open NinoDLC opened this issue 2 years ago • 2 comments
trafficstars

Use case

I read BLE characteristics and send them throught a Flow for the rest of my application to act on it. The BLE characteristics are based on real world events (think of something like a rowing machine). Sometimes, the Flow would emit TONS of values in a very short time frame, sometimes it wouldn't emit for several seconds. I want to limit the "rate" of emission to a maximum of, say, 10 / second. Any higher value is putting the code to unnecessary stress.

Currently, the 2 available APIs won't help me :

  • .sample() is great but if no value is emitted during the sampling, the flow is stopped. Unreliable in my case.
  • .debounce() won't produce any intermediate value until the flow is "at rest"

The Shape of the API

  • The first value would be emitted immediately.
  • Any subsequent value would be ignored until the duration between the previous emission and current one is greater or equal to the given duration.
flow {
    repeat(10) {
        emit(it)
        delay(110)
    }
    delay(300)
    emit(42)
}.throttle(200)

produces the following emissions
0, 2, 4, 6, 8, 10, 42

Prior Art

Even if it's not really and argument, Rx has it and it's convenient. https://rxmarbles.com/#throttle

NinoDLC avatar Aug 11 '23 10:08 NinoDLC

See also https://github.com/Kotlin/kotlinx.coroutines/issues/460

dkhalanskyjb avatar Sep 05 '23 12:09 dkhalanskyjb

Currently, you can use my extension https://github.com/hoc081098/FlowExt

hoc081098 avatar Sep 15 '23 13:09 hoc081098