NAME

    Memcached::RateLimit - Sliding window rate limiting with Memcached

VERSION

    version 0.09

SYNOPSIS

     use Memcached::RateLimit;
     
     my $rl = Memcached::RateLimit->new("memcache://localhost:11211");
     $rl->error_handler(sub ($rl, $message) {
       warn "rate limit error: $message";
     });
     
     # allow 30 requests per minute
     if($rl->rate_limit("resource", 1, 30, 60))
     {
       # rate limit exceeded
     }

DESCRIPTION

    This module implements rate limiting logic. It is intended for high
    volume websites that require limits on the access or modification to
    resources. It is implemented using Rust and FFI::Platypus, so you will
    need the rust toolchain in order to install this module.

    Why Rust? Well none of the Perl Memcache clients I found supported TLS,
    and the Rust memcache crate <https://crates.io/crates/memcache> did.
    Also Rust is fast and has a number of safety checks that give me
    confidence that it won't crash our app.

    The actual algorithm is based one used by Bugzilla, and by default it
    will "fail open", meaning if for some reason the client cannot connect
    to the Memcached server, it will allow the request.

CONSTRUCTOR

 new

     my $rl = Memcached::RateLimit->new($url);
     my $rl = Memcached::RateLimit->new(\%config);

    Create a new instance of Memcached::RateLimit. The URL should be of the
    form shown in the synopsis above.

    The following schemes are supported:

    memcache

    memcache+tcp

    memcache+tls

    memcache+udp

    memcache+unix

    You can append these query parameters to the URL:

    connect_timeout

      Connect timeout in seconds. May be specified as a floating point,
      that is 0.2 is 20 milliseconds.

    protocol

      If set to ascii this will use the ASCII protocol instead of binary.

    tcp_nodelay

      Boolean true or false.

    timeout

      IO timeout in seconds. May be specified as a floating point, that is
      0.2 is 20 milliseconds.

    verify_mode

      For TLS, this can be set to none or peer.

    [version 0.03]

    You can provide a %Config hash instead of a URL. All of the query
    parameters mentioned above can be provided in addition to these:

    scheme

      The scheme (example: memcache or memcache+tls).

    host

      The server hostname or IPv4/IPv6 address.

    port

      The TCP or UDP port to connect to.

    read_timeout

      The read timeout in seconds. May be specified as a floating point,
      that is 0.2 is 20 milliseconds.

    write_timeout

      The write timeout in seconds. May be specified as a floating point,
      that is 0.2 is 20 milliseconds.

    retry

      [version 0.04]

      The default instance number of retries.

METHODS

 rate_limit

     my $limited = $rl->rate_limt($name, $size, $rate_max, $rate_seconds);
     my $limited = $rl->rate_limt($name, $size, $rate_max, $rate_seconds, $retry);

    This method returns a boolean true, if a request of $size exceeds the
    rate limit of $rate_max over the past $rate_seconds. If you only want
    to rate limit the number of requests then you can set $size to 1.

    This method will return a boolean false, and increment the appropriate
    counters if the requests fits within the rate limit.

    This method will also return boolean false, if it is unable to connect
    to or otherwise experiences an error talking to the memcached server.
    In this case it will also call the error handler.

    [version 0.04]

    If $retry is provided then if there are errors talking to memcached, it
    will be attempted $retry times. If this parameter is not provided, then
    the default instance retry limit will be used, and if there is not
    instance default the class default of 1 will be used.

 set_read_timeout

     $rl->set_read_timeout($secs);

    Sets the IO Read timeout to $secs, may be fractional.

 set_write_timeout

     $rl->set_write_timeout($secs);

    Sets the IO Write timeout to $secs, may be fractional.

 error_handler

     $rl->error_handler(sub ($rl, $message) {
       ...
     });

    This method will set the error handler, to be called in the case of an
    error with the memcached server. It will pass in the instance of
    Memcached::RateLimit as $rl and a diagnostic as $message. Since this
    module will fail open, it is probably useful to increment error
    counters and provide diagnostics with this method to your monitoring
    system.

 final_error_handler

    [version 0.04]

     $rl->final_error_handler(sub ($rl, $message) {
     });

    This method is like the error_handler method, but it only gets called
    at the end if none of the retry attempts succeed. The last error
    message is passed in.

SEE ALSO

    Cache::Memcached::Fast

    Redis::RateLimit

AUTHOR

    Author: Graham Ollis <plicease@cpan.org>

    Contributors:

    Dylan Hardison (DHARDISON)

COPYRIGHT AND LICENSE

    This software is copyright (c) 2022 by Graham Ollis.

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