Provided by: libschedule-ratelimiter-perl_0.01-5_all bug

NAME

       Schedule::RateLimiter - prevent events from happening too quickly.

SYNOPSIS

         use Schedule::RateLimiter;

         # Don't let this event happen more than 5 times in a 60 second period.
         my $throttle = Schedule::RateLimiter->new ( iterations => 5,
                                             seconds    => 60 );

         # Cycle forever, but not too fast.
         while ( 1 ) {
             $throttle->event();
             &do_something;
         }

DESCRIPTION

       This module provides a way to voluntarily restrict how many times a given action may take
       place within a specified time frame.  Such a tool may be useful if you have written
       something which periodically polls some public resource and want to ensure that you do not
       overburden that resource with too many requests.

       Initially, one might think that solving this problem would be as simple as sleeping for
       the number of seconds divided by the number of iterations in between each event.  However,
       that would only be correct if the event took no time at all.

       If you know exactly how much time each event is going to take then you could build an even
       more complicated one-liner such as this:

         sleep( (seconds / iterations) - single_event_time )

       This module is intended to address the other cases when the exact run-time of each event
       is unknown and variable.  This module will try very hard to allow an event to happen as
       many times as possible without exceeding the specified bounds.

       For example, suppose you want to write something that checks an 'incoming' directory once
       a minute for files and then does something with those files if it finds any.  If it takes
       you two seconds to process those files, then you want to wait 58 seconds before polling
       the directory again.  If it takes 30 seconds to process those files, then you only want to
       wait 30 seconds.  And if it takes 3 minutes, then you want to poll the directory again
       immediately as soon as you are done.

         my $throttle = Schedule::RateLimiter->new ( seconds => 60 );
         &poll_and_process while ( $throttle->event );

METHODS

   " new() "
       Creates and returns a new Schedule::RateLimiter object.

       The constructor takes up to three parameters:

       •   block (default: true)

           This parameter accepts a true or false value to set the default "block" behavior on
           future calls to event().  It makes it more convenient to turn blocking off for an
           entire object at a time.

       •   iterations (default: 1)

           This specifies the number of times an event may take place within the given time
           period.  This must be a positive, non-zero integer.

       •   seconds (required)

           This specifies the minimum number of seconds that must transpire before we will allow
           (iterations + 1) events to happen.  A value of 0 disables throttling.  You may specify
           fractional time periods.

       example:

         my $throttle = Schedule::RateLimiter->new ( iterations => 2,
                                             seconds    => 10 );

         # Event 1
         $throttle->event();
         # Event 2
         $throttle->event();
         # Event 3
         $throttle->event();
         # 10 seconds will have transpired since event 1 at this point.
         # Event 4
         $throttle->event();
         # 10 seconds will have transpired since event 2 at this point.

   " event() "
       Called to signal the beginning of an event.  This method will return true or false to
       indicate if it is ok to proceed with the event.  This method uses Time::HiRes to do its
       calculations and sleeping, so the precision of this method will be the same as the
       precision of Time::HiRes on your platform.

       Takes one (optional) parameter:

       •   block (default: true)

           If set to a false value, this method will do a non-blocking check to see if it is ok
           for the event to occur.  If it is not ok, this method will return a false value and
           assume that the event did not take place.  Otherwise, this method will return a true
           value and assume that the event did take place.

       example:

         # Stop when the code moves too fast.
         while ( 1 ) {
             if ($throttle->event( block => 0 )) {
                 &do_something;
             } else {
                 die 'I went too fast!';
             }
         }

BUGS

       This module needs to keep a record of when every iteration took place, so if you are
       allowing a large number of iterations to happen in the given time period, this could
       potentially use a lot of memory.

KNOWN ISSUES

       If you have multiple iterations that typically happen very quickly, and you want to limit
       them in a long period of time, they will "clump" together.  That is, they all happen at
       just about the same time, and then the system waits for a long period before doing the
       same "clump" again.  That's just the nature of the best-fit algorithm.  Anything that is
       done to try to separate single events with longer waits than necessary will potentially
       create a sub-optimal situation if an event in the future takes longer than expected.  If
       you really want all of your events to start at even time periods apart from each other,
       then set the number of iterations to 1 and adjust the number of seconds accordingly.

AUTHOR

       Daniel J. Wright, <wright@pair.com>

SEE ALSO

       The POE module provides a more heavyweight solution to this problem as well.

       perl.