spring-attic / reactive-streams-commons

A joint research effort for building highly optimized Reactive-Streams compliant operators.
Apache License 2.0
357 stars 51 forks source link

Throttling on leading and trailing edge #6

Closed bripkens closed 8 years ago

bripkens commented 8 years ago

Request

It would be great when Reactor would support throttling on leading and trailing edge. This is quite a common use case when working on applications that provide data to some kind of reactive user interface, but may be an interesting feature in general.

Disclaimer: This ticket describes throttling requirements from the perspective of a UI. Various kinds of consumers may have the same requirements, even though they are not explicitly mentioned.

What does this mean?

The popular JS library lodash implements this throttling behavior as a default (as mentioned before, quite a common use case for UI applications). Instead of trying to explain this with words, please check out the following JS Bin which shows the behavior in action:

For easier reference, here the example logic and resulting output:

const windowSize = 100;
const fn = _.throttle(v => console.log(v), windowSize);

fn('a');                                     // start of first window
setTimeout(() => fn('b'), windowSize * 0.5); // in first window, but dropped due to successive message
setTimeout(() => fn('c'), windowSize * 0.9); // last message in first window

setTimeout(() => fn('d'), windowSize * 1.2); // first message in new window

// expected output:
// a
// c
// d

Why is this interesting?

In reactive UIs, throttling logic which emits only on a single edge, i.e. either leading or trailing edge, is insufficient as:

ifesdjeen commented 8 years ago

+1

akarnokd commented 8 years ago

Rsc has three operators that can support such UI behavior already:

Maybe these are not exposed or named differently in reactor-core/stream.

bripkens commented 8 years ago

@akarnokd: I not sure I understand how these could be defined in order to achieve this behavior. Simply chaining throttleFirst and throttleLast would not result in the desired behavior.

smaldini commented 8 years ago

Documentation with marble coming but I was also trying to understand precisely what's wrong with http://projectreactor.io/stream/docs/api/reactor/rx/Stream.html#throttleFirst-reactor.fn.Function- http://projectreactor.io/stream/docs/api/reactor/rx/Stream.html#throttleTimeout-reactor.fn.Function-

smaldini commented 8 years ago

I think I get it, please confirm :dancer: You want to emit the first And last value of a given window ? E.g. sampleStartStop.

ifesdjeen commented 8 years ago

I'll try to explain the way I have understood:

:)

smaldini commented 8 years ago

Ok makes sense, so A [---B-[[-----] ---]] C [-------] D

bripkens commented 8 years ago

Not exactly. I'd recommend inspecting the JSBin referenced above and playing with the test. I can try to explain it in words, but that might not be as accurate :)

ifesdjeen commented 8 years ago

Ok, I'd say just suggest to submit a PR for exactly what you want :) you understand the problem better than all of us anyways :))

smaldini commented 8 years ago

If you can hand draw or similar, I suggest a marble diagram like

ifesdjeen commented 8 years ago

I guess that one is not relevant anymore.