Sub::Throttler::algo - base class for throttling algorithms
This document describes Sub::Throttler::algo version v0.2.5 =head1 SYNOPSIS
package Sub::Throttler::YourCustomAlgo; use parent qw( Sub::Throttler::algo ); sub new { ... } sub load { ... } sub save { ... } sub acquire { ... } sub try_acquire { ... } sub release { ... } sub release_unused { ... } package main; $throttle->apply_to_methods(Mojo::UserAgent => qw( get post ));
This is a base class useful for implementing throttling algorithm plugins for Sub::Throttler. For more details check "Implementing throttle algorithms/plugins" in Sub::Throttler.
Nothing.
All methods listed in this section isn't implemented in Sub::Throttler::algo, but they usually should be provided by algorithm module inherited from this base class. They isn't required by throttling engine so your algorithm may choose to not implement them, but they usually needed for user so it's good idea to provide them.
my $throttle = Sub::Throttler::YourCustomAlgo->new(...);
Create and return new instance of this algorithm.
Supported params depends on concrete algorithm, for example see "new" in Sub::Throttler::Limit, "new" in Sub::Throttler::Periodic::EV.
It won't affect throttling of your functions/methods until you'll call "apply_to_functions" or "apply_to_methods" or "apply_to" or "throttle_add" in Sub::Throttler. You don't have to keep returned object after you've configured throttling by calling these methods.
my $throttle = Sub::Throttler::YourCustomAlgo->load($state);
Parameter $state is one returned by "save", with details about object configuration and acquired resources.
$state
While processing $state load() should take in account what it may be returned by save() from different version of this algorithm module and difference in time between calls to save() and load() (including time jump backward or reset of monotonic clock because of OS reboot).
Which data is actually restored by load() depends on algorithm - in some cases it won't be possible to release resources acquired while previous run of this application (when save() was called), so it may be a bad idea to restore acquired state of these resources while load().
my $state = $throttle->save(...);
Return complex perl data structure with details about current configuration and acquired resources (also usually contain current version and time details needed for "load").
User is supposed to serialize returned value (for ex. into JSON format), save it into file/database, and use later with "load" if she wanna keep information about used resources between application restarts (to protect against occasional crashes it make sense to save current state every few seconds/minutes).
Methods listed in this section are implemented in Sub::Throttler::algo.
$throttle = $throttle->apply_to_functions; $throttle = $throttle->apply_to_functions('func', 'Some::func2');
When called without params will apply to all functions with throttling support. When called with list of function names will apply to only these functions (if function name doesn't contain package name it will use caller's package for that name).
All affected functions will use 1 resource named "default".
1
"default"
$throttle = $throttle->apply_to_methods; $throttle = $throttle->apply_to_methods('Class'); $throttle = $throttle->apply_to_methods($object); $throttle = $throttle->apply_to_methods(Class => qw( method method2 )); $throttle = $throttle->apply_to_methods($object => qw( method method2 ));
When called without params will apply to all methods with throttling support. When called only with 'Class' or $object param will apply to all methods of that class/object. When given list of methods will apply only to these methods.
'Class'
$object
In 'Class' case will apply both to Class's methods and methods of any object of that Class.
All affected methods will use 1 resource named "default".
$throttle = $throttle->apply_to(sub { my ($this, $name, @params) = @_; if (!$this) { # it's a function, $name contains package: # $name eq 'main::func' } elsif (!ref $this) { # it's a class method: # $this eq 'Class::Name' # $name eq 'new' } else { # it's an object method: # $this eq $object # $name eq 'method' } return; # do no throttle it return undef; # do no throttle it return {}; # do no throttle it return { key=>1 }; # throttle it by acquiring 1 resource 'key' return { k1=>2, k2=>5 }; # throttle it by atomically acquiring: # 2 resources 'k1' and 5 resources 'k2' });
This is most complex but also most flexible way to configure throttling - you can introspect what function/method and with what params was called and return which and how many resources it should acquire before run.
It's unlikely you'll need to manually manage resources, but it's possible to do if you want this - just be careful because if you acquire and don't release resource used to throttle your functions/methods they may won't be run anymore.
All methods listed below isn't implemented in Sub::Throttler::algo, they must be provided by algorithm module inherited from this base class.
$throttle = $throttle->acquire($id, $key, $quantity);
Blocking version of "try_acquire" - it will either successfully acquire requested resource or throw exception. If this resource is not available right now but will become available later (this depends on throttling algorithm) it will wait (using sleep()) until resource will be available.
my $is_acquired = $throttle->try_acquire($id, $key, $quantity);
The throttling engine uses Scalar::Util::refaddr($done) for $id (large number), so it's safe for you to use either non-numbers as $id or refaddr() of your own variables.
Scalar::Util::refaddr($done)
$id
$throttle->try_acquire('reserve', 'default', 3) || die; $throttle->try_acquire('extra reserve', 'default', 1) || die;
Will throw if some $key will be acquired more than once by same $id or $quantity is non-positive.
$key
$quantity
$throttle = $throttle->release($id);
Release all resources previously acquired by one or more calls to "acquire" or "try_acquire" using this $id (this may or may not make them immediately available for acquiring again depending on plugin/algorithms).
$throttle = $throttle->release_unused($id);
Release all resources previously acquired by one or more calls to "acquire" or "try_acquire" using this $id.
Treat these resources as unused, to make it possible to reuse them as soon as possible (this may or may not differ from "release" depending on plugin/algorithms).
Please report any bugs or feature requests through the issue tracker at https://github.com/powerman/perl-Sub-Throttler/issues. You will be notified automatically of any progress on your issue.
This is open source software. The code repository is available for public review and contribution under the terms of the license. Feel free to fork the repository and submit pull requests.
https://github.com/powerman/perl-Sub-Throttler
git clone https://github.com/powerman/perl-Sub-Throttler.git
MetaCPAN Search
https://metacpan.org/search?q=Sub-Throttler
CPAN Ratings
http://cpanratings.perl.org/dist/Sub-Throttler
AnnoCPAN: Annotated CPAN documentation
http://annocpan.org/dist/Sub-Throttler
CPAN Testers Matrix
http://matrix.cpantesters.org/?dist=Sub-Throttler
CPANTS: A CPAN Testing Service (Kwalitee)
http://cpants.cpanauthors.org/dist/Sub-Throttler
Alex Efros <powerman@cpan.org>
This software is Copyright (c) 2014-2015 by Alex Efros <powerman@cpan.org>.
This is free software, licensed under:
The MIT (X11) License
To install Sub::Throttler, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Sub::Throttler
CPAN shell
perl -MCPAN -e shell install Sub::Throttler
For more information on module installation, please visit the detailed CPAN module installation guide.