Why not adopt me?
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.