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

Stream throttling #8492

Closed
DartBot opened this issue Feb 12, 2013 · 6 comments
Closed

Stream throttling #8492

DartBot opened this issue Feb 12, 2013 · 6 comments
Labels
area-library closed-obsolete Closed as the reported issue is no longer relevant core-2 needs-info We need additional information from the issue author (auto-closed after 14 days if no response) P2 A bug or feature request we're likely to work on type-enhancement A request for a change that isn't a bug

Comments

@DartBot
Copy link

DartBot commented Feb 12, 2013

This issue was originally filed by @seaneagan


It would be useful to be able to throttle Stream events. Something like:

/// Returns a Stream with the same events as this Stream, but the events never occur within [duration] of eachother
Stream<E> throttle(Duration duration);

There are cases where you want to discard the extra events which occur before the Duration is up, such as UI events, and other cases, such as IO where you generally want to just delay the extra events, so probably need either an optional boolean argument or two separate methods.

Example:

button.onClick.throttle(new Duration(seconds: 1)).then(react);

@lrhn
Copy link
Member

lrhn commented Feb 13, 2013

Is throttling by time the most useful approach?
The need to throttle should come from the back-end being swamped with events faster than it can handle them. In that case it should pause the stream until it's un-swamped again, but using a fixed duration is probably not optimal.

If it's because you only want to poll the output of a stream every <duration>, I'd just store the events in a variable, and read it from a repeating timer.

So, what I'm asking is: Are you sure this is really a common need that belongs in the standard libary?
(If you are only using it for unit-testing, I'll write you a StreamTransformer you can use for that :).


Removed Type-Defect label.
Added Type-Enhancement, Area-Library, NeedsInfo labels.

@DartBot
Copy link
Author

DartBot commented Feb 13, 2013

This comment was originally written by @seaneagan


It is definitely useful for UI Event Streams. Here are some links to check out:

http://benalman.com/projects/jquery-throttle-debounce-plugin/
http://underscorejs.org/#throttle
http://msdn.microsoft.com/en-us/library/hh229298(v=vs.103).aspx

I'd have to do a little more research on IO Stream throttling, as I don't have as much experience with that.

@DartBot
Copy link
Author

DartBot commented Feb 25, 2013

@DartBot
Copy link
Author

DartBot commented May 25, 2013

This comment was originally written by @MarkBennett


In reply to the first comment by lrn@google.com, I'm just curious if there are other examples of applications throttling by workload rather than time? Would a syntax like this work?

    Future lookUpDefinition(String word) {
      return Google.lookup(word).then((definitions) => defintions.first);
    }
    
    main() {
      StreamController controller = new StreamController(onListen: (ctrl) {
        ctrl..add("Test")..add("Bob")..add("Christopher");
      });
      Stream<String> stream = controller.stream;

      // Only the first event in the stream is processed
      // All others are ignored until the future is resolved
      // The result of the future is added to the sink, so throttleUntil()
      // is also a StreamTransformer
      stream.throttleUntil(lookUpDefinition).listen((definition) {
       print("The definition is, '$definition'.");
      });

      // Only one event is processed within a five second period
      stream.throttleFor(new Duration(seconds: 5)).
        listen((word) {
          lookUpDefinition(word).then((definition) {
            print("The definition is, '$definition'.");
          });
        });
    }

Debouncing really only makes sense to me in the context of a timer, so the syntax could look like this:

      // Wait for 200 milliseconds before calling this for the first time
      // Only the last event received during this time is handled
      stream.debounceFor(new Duration(milliseconds: 200)).listen((word) {
        lookUpDefinition(word).then((definition) {
          print("The definition is, '$definition'");
        });
      });

Given that throttle or debounce a stream seems like a common transformation in many UIs including it in the standard library would definately have value. I know the throttle and debounce functions are well used in Underscore for example.

Thoughts?

@DartBot
Copy link
Author

DartBot commented Oct 13, 2014

This comment was originally written by @seaneagan


This is now implemented in the rate_limit package:

https://pub.dartlang.org/packages/rate_limit

@DartBot DartBot added Type-Enhancement area-library needs-info We need additional information from the issue author (auto-closed after 14 days if no response) labels Oct 13, 2014
@kevmoo kevmoo added P2 A bug or feature request we're likely to work on type-enhancement A request for a change that isn't a bug and removed Priority-Medium labels Mar 1, 2016
@lrhn lrhn added the core-m label Aug 11, 2017
@floitschG floitschG added core-2 and removed core-m labels Aug 29, 2017
@matanlurey matanlurey added the closed-obsolete Closed as the reported issue is no longer relevant label Jun 21, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-library closed-obsolete Closed as the reported issue is no longer relevant core-2 needs-info We need additional information from the issue author (auto-closed after 14 days if no response) P2 A bug or feature request we're likely to work on type-enhancement A request for a change that isn't a bug
Projects
None yet
Development

No branches or pull requests

5 participants