Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Operators: Throttle and Debounce #368

Merged

Conversation

benjchristensen
Copy link
Member

This adds throttleFirst, throttleLast (alias of sample) and debounce (aliased with throttleWithTimeout).

This merges pull request #258.

Unfortunately the Rx throttle operator behavior is actually debounce, not throttle. This pull request tries to address that.

Here is a good place to get a description of throttle versus debounce: http://drupalmotion.com/article/debounce-and-throttle-visual-explanation

Debounce: Think of it as "grouping multiple events in one". Imagine that you go home, enter in the elevator, doors are closing... and suddenly your neighbor appears in the hall and tries to jump on the elevator. Be polite! and open the doors for him: you are debouncing the elevator departure. Consider that the same situation can happen again with a third person, and so on... probably delaying the departure several minutes.

Throttle: Think of it as a valve, it regulates the flow of the executions. We can determine the maximum number of times a function can be called in certain time. So in the elevator analogy.. you are polite enough to let people in for 10 secs, but once that delay passes, you must go!

Other links includes:

I feel we need some kind of throttle* operator name as an alias to debounce to help people discover it, especially those coming from Rx.Net or RxJS. I'm not fond of throttleWithTimeout which is what I have it as right now. Perhaps throttleViaDebounce even though that doesn't actually make sense?

I do not want to use throttle because it's not actually the definition of throttle. To confirm this I have asked over a dozen server-side engineers what their definition of throttle is and their expectations of an operator is. It never matches the Rx definition and they are always surprised by the debounce behavior.

I have included throttleLast as an alias to sample so that as people start typing throttle... it prompts them for the different options and discoverability will be improved instead of knowing to go look for sample.

The throttleFirst operator is included as an efficient approach to throttling tht does not involve ticking time, intervals or buffering in any way. It simply allows an onNext value through if the last onNext event was greater than X time units ago. All others are discarded. This matches server-side throttling expectations and is limited overhead.

Questions:

  1. Is there a better name for throttleWithTimeout as an alias to debounce?
  2. Does the documentation sufficiently explain the different strategies?
  3. If ambitious in your review, does anyone see concurrency bugs?

michaeldejong and others added 16 commits May 5, 2013 10:49
…xJava into throttle-merge

Conflicts:
	rxjava-core/src/main/java/rx/Observable.java
	rxjava-core/src/main/java/rx/concurrency/TestScheduler.java
Another take on `throttle` … I believe this matches Rx.Net behavior.

This will wait until timeout value has passed without any further values before emitting the received value.
Another take on `throttle` … this delivers the first value in each window.
…xJava into throttle

Conflicts:
	rxjava-core/src/main/java/rx/Observable.java
	rxjava-core/src/main/java/rx/concurrency/TestScheduler.java
Conflicts:
	rxjava-core/src/main/java/rx/Observable.java
Conflicts:
	rxjava-core/src/main/java/rx/Observable.java
	rxjava-core/src/main/java/rx/operators/OperationThrottle.java
Conflicts:
	rxjava-core/src/main/java/rx/Observable.java
- javadocs explaining differences
- link between throttleLast and sample (aliase)
- refactored throttleFirst to be a more efficient implementations
- concurrency changes to throttleWithTimeout
…tely is the poorly named Rx Throttle operator.

http://drupalmotion.com/article/debounce-and-throttle-visual-explanation

Debounce: Think of it as "grouping multiple events in one". Imagine that you go home, enter in the elevator, doors are closing... and suddenly your neighbor appears in the hall and tries to jump on the elevator. Be polite! and open the doors for him: you are debouncing the elevator departure. Consider that the same situation can happen again with a third person, and so on... probably delaying the departure several minutes.

Throttle: Think of it as a valve, it regulates the flow of the executions. We can determine the maximum number of times a function can be called in certain time. So in the elevator analogy.. you are polite enough to let people in for 10 secs, but once that delay passes, you must go!

http://unscriptable.com/2009/03/20/debouncing-javascript-methods/
http://www.illyriad.co.uk/blog/index.php/2011/09/javascript-dont-spam-your-server-debounce-and-throttle/
@cloudbees-pull-request-builder

RxJava-pull-requests #262 SUCCESS
This pull request looks good

@benjchristensen
Copy link
Member Author

I would appreciate feedback on this today so I can merge (or fix with feedback) tomorrow (Wednesday US time) and get ready to release version 0.13.

@DavidMGross
Copy link
Collaborator

I've created marble diagrams for these new methods. If you want to include
them in the javadocs, you can use a similar URL pattern to those that are
already found there. The diagrams are called:

throttleLast.png
throttleFirst.png
throttleWithTimeout.png
debounce.png

@benjchristensen
Copy link
Member Author

Thank you @DavidMGross

One change to make ... on throttleFirst there would not be a delay in delivering, thus it would emit red, yellow, turquoise immediately, not after a delay. That's the big difference with 'throttleFirst', there is no scheduling or delaying, thus no threading overhead. It only skips until skipDuration has passed since the last onNext was emitted then emits the next onNext it receives.

@cloudbees-pull-request-builder

RxJava-pull-requests #264 SUCCESS
This pull request looks good

@benjchristensen
Copy link
Member Author

No feedback so I'm moving forward with this.

benjchristensen added a commit that referenced this pull request Sep 11, 2013
@benjchristensen benjchristensen merged commit 90f679f into ReactiveX:master Sep 11, 2013
@benjchristensen benjchristensen deleted the throttle-and-debounce branch September 11, 2013 16:53
* @see {@link #throttleWithTimeout};
*/
public Observable<T> debounce(long timeout, TimeUnit unit, Scheduler scheduler) {
return create(OperationDebounce.debounce(this, timeout, unit));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

scheduler has no effect here...

rickbw pushed a commit to rickbw/RxJava that referenced this pull request Jan 9, 2014
jihoonson pushed a commit to jihoonson/RxJava that referenced this pull request Mar 6, 2020
…onfiguration should be auto configured before EndpointAutoConfiguration.
jihoonson pushed a commit to jihoonson/RxJava that referenced this pull request Mar 6, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants