Last active
February 10, 2023 10:58
-
-
Save DarkGhostHunter/033e85faceb3d69492ea81bd9bf328e9 to your computer and use it in GitHub Desktop.
A class that throttles it's target methods calls.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Throttler; | |
use Illuminate\Cache\RateLimiter; | |
class Throttler | |
{ | |
/** | |
* Target to rate limit. | |
* | |
* @var object | |
*/ | |
protected $target; | |
/** | |
* Rate Limiter instance. | |
* | |
* @var \Illuminate\Cache\RateLimiter | |
*/ | |
protected $limiter; | |
/** | |
* Maximum tries inside the decay window. | |
* | |
* @var int | |
*/ | |
protected $maxAttempts; | |
/** | |
* Window of seconds to make tries. | |
* | |
* @var int | |
*/ | |
protected $decaySeconds; | |
/** | |
* Create a new Throttler instance. | |
* | |
* @param \Illuminate\Cache\RateLimiter $limiter | |
*/ | |
public function __construct(RateLimiter $limiter) | |
{ | |
$this->limiter = $limiter; | |
} | |
/** | |
* Sets the limits to use with the Rate Limiter. | |
* | |
* @param int $tries | |
* @param int $minutes | |
* @return Throttler | |
*/ | |
public function throttle(int $tries, int $minutes) | |
{ | |
$this->maxAttempts = $tries; | |
$this->decaySeconds = $minutes * 60; | |
return $this; | |
} | |
/** | |
* Sets the target object to throttle its methods. | |
* | |
* @param object $target | |
* @return $this | |
*/ | |
public function setTarget(object $target) | |
{ | |
$this->target = $target; | |
return $this; | |
} | |
/** | |
* Handle dynamically calling the object. | |
* | |
* @param string $name | |
* @param mixed $arguments | |
* @return object | |
*/ | |
public function __call($name, $arguments) | |
{ | |
$key = get_class($this->target) . '@' . $name; | |
if (! $this->limiter->tooManyAttempts($key, $this->maxAttempts)) { | |
$this->target->{$name}(...$arguments); | |
$this->limiter->hit($key, $this->decaySeconds); | |
} | |
return $this->target; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment