Tom van der Woerdt
and 1 contributors

NAME

Throttle::Adaptive - implementation of the "adaptive throttling" algorithm by Google

VERSION

version 0.001

DESCRIPTION

Perl implementation of the adaptive throttling algorithm described in Google's SRE book, used to proactively reject requests to overloaded services.

EXAMPLE

    use Throttle::Adaptive;

    my $THROTTLE= Throttle::Adaptive->new;
    # my $THROTTLE= Throttle::Adaptive->new(
    #     ratio => 2,
    #     time => 120,
    # );

    sub do_request {
        my ($url)= @_;
        if ($THROTTLE->should_fail) {
            die "Proactively rejecting request which is likely to fail";
        }

        my $response= http_request($url);
        $THROTTLE->count($response->is_error && $response->error->is_timeout);

        if ($response->is_error) {
            die "Request failed: ".$reponse->error->as_string;
        }

        return $response->body;
    }

API

Construct a new Throttle::Adaptive object via the new method, which accepts the named arguments ratio and time respectively indicating the fail:success ratio after which to start rejecting requests (default: 2), and the window size in seconds (default: 120). For most use cases the defaults are sufficient.

    my $throttler= Throttle::Adaptive->new;

This object has two methods, should_fail and count.

should_fail

should_fail should be invoked prior to submitting the request. If this function returns false, the request should not be executed, and an error should be returned to the user. If it returns true, the request should be executed, and count should be used to track the success of the request.

count($error)

count tracks the success of the request once it is known whether it has succeeded. It takes one argument, $error, indicating whether the reason of the request failure is something we would proactively fail for in the future (usually timeouts go into this category, but a HTTP 429 response could also qualify).

    if ($throttler->should_fail) {
        warn "Request skipped: throttler";
        return undef;
    }
    my $response = perform_request(...);
    if (is_timeout($response)) {
        $throttler->count(1);
    } else {
        $throttler->count(0);
    }
    return $response;

CAVEATS

One should make sure to only invoke count on requests that have been submitted, and not in situations where should_fail indicates that the request should not be performed at all.

AUTHOR

Tom van der Woerdt <info@tvdw.eu>

COPYRIGHT AND LICENSE

This software is copyright (c) 2019 by Tom van der Woerdt.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.