NAME
    Object::RateLimiter - A flood control (rate limiter) object

SYNOPSIS
      use Object::RateLimiter;

      my $ctrl = Object::RateLimiter->new(
        events  => 3,
        seconds => 5
      );

      # Run some subs, as a contrived example;
      # no more than 3 in 5 seconds, per our constructor above:
      my @work = (
        sub { "foo" },  sub { "bar" },
        sub { "baz" },  sub { "cake" },
        # ...
      );

      while (my $some_item = shift @work) {
        if (my $delay = $ctrl->delay) {
          # Delayed $delay seconds.
          sleep $delay;
        } else {
          # No delay.
          print $some_item->()
        }
      }

      # Clear the event history if it's stale:
      $ctrl->expire;

      # Clear the event history unconditionally:
      $ctrl->clear;

DESCRIPTION
    This is a generic rate-limiter object, implementing the math described
    in <http://www.perl.com/pub/2004/11/11/floodcontrol.html>.

    The algorithm is fairly simple; the article linked above contains an
    in-depth discussion by Vladi Belperchinov-Shabanski (CPAN:
    <http://www.metacpan.org/author/CADE>):

      $delay =
        ( 
          $oldest_timestamp + 
          ( $seen_events * $limit_secs / $event_limit ) 
        )
        - time()

    This module uses Time::HiRes to provide support for fractional seconds.

  new
      my $ctrl = Object::RateLimiter->new(
        events  => 3,
        seconds => 5
      );

    Constructs a new rate-limiter with a clean event history.

  clone
      my $new_ctrl = $ctrl->clone( events => 4 );

    Clones an existing rate-limiter; new options can be provided, overriding
    previous settings.

    The new limiter contains a clone of the event history; the old
    rate-limiter is left untouched.

  clear
      $ctrl->clear;

    Clears the event history.

    Always returns true.

  delay
      if (my $delay = $ctrl->delay) {
        sleep $delay;  # ... or do something else
      } else {
        # Not delayed.
        do_work;
      }

    The "delay()" method determines if some work can be done now, or should
    wait.

    When called, event timestamps are considered; if we have exceeded our
    limit, the delay in (possibly fractional) seconds until the event would
    be allowed is returned.

    A return value of 0 indicates that the event does not need to wait.

  events
    Returns the events limit the object was constructed with.

  expire
      $ctrl->expire;

    Clears the event history if the last seen event is outside of our time
    window.

    Returns true if "clear" was called.

    (You're not required to call "expire()", but it can be useful to force a
    cleanup.)

  seconds
    Returns the seconds limit the object was constructed with.

AUTHOR
    Jon Portnoy <avenj@cobaltirc.org>

    Based on the math from Algorithm::FloodControl as described in an
    article written by the author:
    <http://www.perl.com/pub/2004/11/11/floodcontrol.html>

    Licensed under the same terms as Perl.

