Skip to content

Commit

Permalink
Merge pull request #1 from paultcochrane/pr/doc-fixes
Browse files Browse the repository at this point in the history
Various documentation fixes and improvements
  • Loading branch information
kappa committed Jul 1, 2016
2 parents 81e6975 + f255a46 commit d433f2a
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 78 deletions.
79 changes: 40 additions & 39 deletions README.md
Expand Up @@ -15,7 +15,7 @@ Algorithm::TokenBucket - Token bucket rate limiting algorithm
sleep 0.1;
# do things
}

# process 3 items because we now can
process(3);

Expand Down Expand Up @@ -44,58 +44,59 @@ Algorithm::TokenBucket - Token bucket rate limiting algorithm

# DESCRIPTION

Token Bucket algorithm is a flexible way of imposing a rate limit
The Token Bucket algorithm is a flexible way of imposing a rate limit
against a stream of items. It is also very easy to combine several
rate-limiters in an `AND` or `OR` fashion.

Each bucket has a constant memory footprint because the
algorithm is based on `information rate`.
Other rate limiters available on CPAN keep track of _ALL_ incoming
items in memory. It allows them to be much more accurate.
Each bucket has a constant memory footprint because the algorithm is based
on the `information rate`. Other rate limiters available on CPAN keep
track of _ALL_ incoming items in memory. It allows them to be much more
accurate.

FYI, `conform`, `count`, `information rate`, `burst size` terms are
taken from [http://linux-ip.net/gl/tcng/node62.html](http://linux-ip.net/gl/tcng/node62.html) page.
FYI, the `conform`, `count`, `information rate`, and `burst size` terms
are taken from the [metering primitives](http://linux-ip.net/gl/tcng/node62.html)
page of the [Linux Traffic Control - Next Generation](http://linux-ip.net/gl/tcng/)
system documentation.

# INTERFACE

## METHODS

- new($$;$$)

The constructor takes as parameters at least `rate of information` in
items per second and `burst size` in items. It can also take current
token counter and last check time but this usage is mostly intended for
restoring a saved bucket. See ["state"](#state).
The constructor requires at least the `rate of information` in items per
second and the `burst size` in items as its input parameters. It can also
take the current token counter and last check time but this usage is mostly
intended for restoring a saved bucket. See ["state()"](#state).

- state()

This method returns the state of the bucket as a list. Use it for storing purposes.
Returns the state of the bucket as a list. Use it for storing purposes.
Buckets also natively support freezing and thawing with [Storable](https://metacpan.org/pod/Storable) by
providing STORABLE\_\* callbacks.
providing `STORABLE_*` callbacks.

- conform($)

This method checks if the bucket contains at least _N_ tokens. In that
case it is allowed to transmit or process _N_ items (not
exactly right because _N_ can be fractional) from the stream. A bucket never
conforms to an _N_ greater than `burst size`.

The method returns a boolean value.
This method returns true if the bucket contains at least _N_ tokens and
false otherwise. In the case that it is true, it is allowed to transmit or
process _N_ items (not exactly right because _N_ can be fractional) from
the stream. A bucket never conforms to an _N_ greater than `burst size`.

- count($)

This method removes _N_ (or all if there are less than _N_ available) tokens from the bucket.
Does not return a meaningful value.
This method removes _N_ (or all if there are fewer than _N_ available)
tokens from the bucket. It does not return a meaningful value.

- until($)

This method returns the number of seconds until _N_ tokens can be removed from the bucket.
It is especially useful in multitasking environments like [POE](https://metacpan.org/pod/POE) where you
cannot busy-wait. One can safely schedule the next conform($N) check in until($N)
seconds instead of checking repeatedly.
This method returns the number of seconds until _N_ tokens can be removed
from the bucket. It is especially useful in multitasking environments like
[POE](https://metacpan.org/pod/POE) where you cannot busy-wait. One can safely schedule the next
`conform($N)` check in `until($N)` seconds instead of checking
repeatedly.

Note that until() does not take into account `burst size`. This means
that a bucket will not conform to _N_ even after sleeping for until($N)
Note that `until()` does not take into account `burst size`. This means
that a bucket will not conform to _N_ even after sleeping for `until($N)`
seconds if _N_ is greater than `burst size`.

- get\_token\_count()
Expand Down Expand Up @@ -127,7 +128,7 @@ allow 2 mails per minute but no more than 20 mails per hour.
}

Now, let's fix the CPU-hogging example from ["SYNOPSIS"](#synopsis) using
["until()"](#until) method.
the ["until($)"](#until) method.

my $bucket = new Algorithm::TokenBucket 100 / 3600, 5;
my $time = Time::HiRes::time;
Expand All @@ -146,16 +147,15 @@ Now, let's fix the CPU-hogging example from ["SYNOPSIS"](#synopsis) using
Documentation lacks the actual algorithm description. See links or read
the source (there are about 20 lines of sparse perl in several subs).

until($N) does not return infinity if $N is greater than `burst
size`. Sleeping for infinity seconds is both useless and hard to
debug.
`until($N)` does not return infinity if `$N` is greater than `burst
size`. Sleeping for infinity seconds is both useless and hard to debug.

# ACKNOWLEDGMENTS

Yuval Kogman contributed the ["until"](#until) method, proper [Storable](https://metacpan.org/pod/Storable) support
Yuval Kogman contributed the ["until($)"](#until) method, proper [Storable](https://metacpan.org/pod/Storable) support
and other things.

Alexey Shrub contributed the ["get\_token\_count"](#get_token_count) method.
Alexey Shrub contributed the ["get\_token\_count()"](#get_token_count) method.

# COPYRIGHT AND LICENSE

Expand All @@ -170,8 +170,9 @@ Alex Kapranoff, <alex@kapranoff.ru<gt>

# SEE ALSO

http://www.eecs.harvard.edu/cs143/assignments/pa1/,
http://en.wikipedia.org/wiki/Token\_bucket,
http://linux-ip.net/gl/tcng/node54.html,
http://linux-ip.net/gl/tcng/node62.html,
[Schedule::RateLimit](https://metacpan.org/pod/Schedule::RateLimit), [Algorithm::FloodControl](https://metacpan.org/pod/Algorithm::FloodControl).
- https://web.archive.org/web/20050320184218/http://www.eecs.harvard.edu/cs143/assignments/pa1/
- http://en.wikipedia.org/wiki/Token\_bucket
- http://linux-ip.net/gl/tcng/node54.html
- http://linux-ip.net/gl/tcng/node62.html
- [Schedule::RateLimit](https://metacpan.org/pod/Schedule::RateLimit)
- [Algorithm::FloodControl](https://metacpan.org/pod/Algorithm::FloodControl)
88 changes: 49 additions & 39 deletions lib/Algorithm/TokenBucket.pm
Expand Up @@ -26,7 +26,7 @@ Algorithm::TokenBucket - Token bucket rate limiting algorithm
sleep 0.1;
# do things
}
# process 3 items because we now can
process(3);
Expand Down Expand Up @@ -55,17 +55,19 @@ Algorithm::TokenBucket - Token bucket rate limiting algorithm
=head1 DESCRIPTION
Token Bucket algorithm is a flexible way of imposing a rate limit
The Token Bucket algorithm is a flexible way of imposing a rate limit
against a stream of items. It is also very easy to combine several
rate-limiters in an C<AND> or C<OR> fashion.
Each bucket has a constant memory footprint because the
algorithm is based on C<information rate>.
Other rate limiters available on CPAN keep track of I<ALL> incoming
items in memory. It allows them to be much more accurate.
Each bucket has a constant memory footprint because the algorithm is based
on the C<information rate>. Other rate limiters available on CPAN keep
track of I<ALL> incoming items in memory. It allows them to be much more
accurate.
FYI, C<conform>, C<count>, C<information rate>, C<burst size> terms are
taken from L<http://linux-ip.net/gl/tcng/node62.html> page.
FYI, the C<conform>, C<count>, C<information rate>, and C<burst size> terms
are taken from the L<metering primitives|http://linux-ip.net/gl/tcng/node62.html>
page of the L<Linux Traffic Control - Next Generation|http://linux-ip.net/gl/tcng/>
system documentation.
=head1 INTERFACE
Expand All @@ -79,10 +81,10 @@ use fields qw/info_rate burst_size _tokens _last_check_time/;
=item new($$;$$)
The constructor takes as parameters at least C<rate of information> in
items per second and C<burst size> in items. It can also take current
token counter and last check time but this usage is mostly intended for
restoring a saved bucket. See L</state>.
The constructor requires at least the C<rate of information> in items per
second and the C<burst size> in items as its input parameters. It can also
take the current token counter and last check time but this usage is mostly
intended for restoring a saved bucket. See L</state()>.
=cut

Expand All @@ -103,9 +105,9 @@ sub _init {

=item state()
This method returns the state of the bucket as a list. Use it for storing purposes.
Returns the state of the bucket as a list. Use it for storing purposes.
Buckets also natively support freezing and thawing with L<Storable> by
providing STORABLE_* callbacks.
providing C<STORABLE_*> callbacks.
=cut

Expand Down Expand Up @@ -140,12 +142,10 @@ sub _token_flow {

=item conform($)
This method checks if the bucket contains at least I<N> tokens. In that
case it is allowed to transmit or process I<N> items (not
exactly right because I<N> can be fractional) from the stream. A bucket never
conforms to an I<N> greater than C<burst size>.
The method returns a boolean value.
This method returns true if the bucket contains at least I<N> tokens and
false otherwise. In the case that it is true, it is allowed to transmit or
process I<N> items (not exactly right because I<N> can be fractional) from
the stream. A bucket never conforms to an I<N> greater than C<burst size>.
=cut

Expand All @@ -160,8 +160,8 @@ sub conform {

=item count($)
This method removes I<N> (or all if there are less than I<N> available) tokens from the bucket.
Does not return a meaningful value.
This method removes I<N> (or all if there are fewer than I<N> available)
tokens from the bucket. It does not return a meaningful value.
=cut

Expand All @@ -176,13 +176,14 @@ sub count {

=item until($)
This method returns the number of seconds until I<N> tokens can be removed from the bucket.
It is especially useful in multitasking environments like L<POE> where you
cannot busy-wait. One can safely schedule the next conform($N) check in until($N)
seconds instead of checking repeatedly.
This method returns the number of seconds until I<N> tokens can be removed
from the bucket. It is especially useful in multitasking environments like
L<POE> where you cannot busy-wait. One can safely schedule the next
C<< conform($N) >> check in C<< until($N) >> seconds instead of checking
repeatedly.
Note that until() does not take into account C<burst size>. This means
that a bucket will not conform to I<N> even after sleeping for until($N)
Note that C<until()> does not take into account C<burst size>. This means
that a bucket will not conform to I<N> even after sleeping for C<< until($N) >>
seconds if I<N> is greater than C<burst size>.
=cut
Expand Down Expand Up @@ -244,7 +245,7 @@ allow 2 mails per minute but no more than 20 mails per hour.
}
Now, let's fix the CPU-hogging example from L</SYNOPSIS> using
L</until()> method.
the L</until($)> method.
my $bucket = new Algorithm::TokenBucket 100 / 3600, 5;
my $time = Time::HiRes::time;
Expand All @@ -263,16 +264,15 @@ L</until()> method.
Documentation lacks the actual algorithm description. See links or read
the source (there are about 20 lines of sparse perl in several subs).
until($N) does not return infinity if $N is greater than C<burst
size>. Sleeping for infinity seconds is both useless and hard to
debug.
C<until($N)> does not return infinity if C<$N> is greater than C<burst
size>. Sleeping for infinity seconds is both useless and hard to debug.
=head1 ACKNOWLEDGMENTS
Yuval Kogman contributed the L</until> method, proper L<Storable> support
Yuval Kogman contributed the L</until($)> method, proper L<Storable> support
and other things.
Alexey Shrub contributed the L</get_token_count> method.
Alexey Shrub contributed the L</get_token_count()> method.
=head1 COPYRIGHT AND LICENSE
Expand All @@ -287,10 +287,20 @@ Alex Kapranoff, E<lt>alex@kapranoff.ru<gt>
=head1 SEE ALSO
http://www.eecs.harvard.edu/cs143/assignments/pa1/,
http://en.wikipedia.org/wiki/Token_bucket,
http://linux-ip.net/gl/tcng/node54.html,
http://linux-ip.net/gl/tcng/node62.html,
L<Schedule::RateLimit>, L<Algorithm::FloodControl>.
=over 4
=item https://web.archive.org/web/20050320184218/http://www.eecs.harvard.edu/cs143/assignments/pa1/
=item http://en.wikipedia.org/wiki/Token_bucket
=item http://linux-ip.net/gl/tcng/node54.html
=item http://linux-ip.net/gl/tcng/node62.html
=item L<Schedule::RateLimit>
=item L<Algorithm::FloodControl>
=back
=cut

0 comments on commit d433f2a

Please sign in to comment.