balambasik/throttler

Throttle any operations

1.0.10 2022-01-21 21:06 UTC

This package is not auto-updated.

Last update: 2024-05-11 08:26:14 UTC


README

Throttler - simple php library.

Designed to limit any action. Minimum configuration, maximum simplicity.

Works with MySql drivers and Memory. Add your driver, implement DriverInterface.

Installation

composer require balambasik/throttler

One example of using

$driver = new MySQLDriver("localhost", "root", "", "throttler", "throttler");
$factory = new ThrottlerFactory($driver);

$registerThrottler = $factory
                ->id($_SERVER["REMOTE_ADDR"])
                ->tag("/api/register")
                ->waitSeconds(5)
                ->create();

// 1 request per 5 seconds per IP, per route - "/api/register"
if($registerThrottler->isLimit()){
    exit("Limit!")
} else {
  // handle request
}

// or -------------------------------------

$registerThrottler->isLimit(function(){
    exit("Limit!")
});

// handle request

Multiple instances

// 1 request per 5 seconds per IP, per route - "/api/register"
$registerThrottler = $factory
                ->id($_SERVER["REMOTE_ADDR"])
                ->tag("/api/register")
                ->waitSeconds(5)
                ->create();

// 1 request per 1 minute per IP, per route - "/api/forgot_password"              
$forgotThrottler = $factory
                ->id($_SERVER["REMOTE_ADDR"])
                ->tag("/api/forgot_password")
                ->waitMinutes(1)
                ->create();


$registerThrottler->isLimit(function(){
    exit("Limit!")
});


$forgotThrottler->isLimit(function(){
    exit("Limit!")
});

Manual mode

By default, method isLimit() logs a hit and checks if the limit has been reached. You can separate these operations.

// 1 request per 5 seconds per IP, per route - "/api/register"
$registerThrottler = $factory
                ->id($_SERVER["REMOTE_ADDR"])
                ->tag("/api/register")
                ->waitSeconds(5)
                ->createManualMode();

// set hit
$registerThrottler->hit();

// check limit
$registerThrottler->isLimit(function(){
    exit("Limit!")
});

The MySql driver needs a table.

CREATE TABLE IF NOT EXISTS `table_name` (
    `id` varchar(10),
    `tag` varchar(10),
    `wait` INT(11) UNSIGNED NOT NULL
    );

ALTER TABLE `table_name` ADD INDEX (`id`, `tag`);

Or call the createTable() method of the MySqlDriver object once

$MySQLDriver = new MySqlDriver("localhost", "login", "password", "dbName", "tableName");
$MySQLDriver->createTable();

InMemory driver

The InMemoryDriver does not require any configuration. For obvious reasons, it can persist state across requests. Therefore, protecting routes with it is a bad idea. It is great for limiting operations within a single request.

$driver = new InMemoryDriver();
$factory = new ThrottlerFactory($driver);
// ...

Licence - MIT.