Skip to content

Instantly share code, notes, and snippets.

@DarkGhostHunter
Last active February 10, 2023 10:58
Show Gist options
  • Save DarkGhostHunter/033e85faceb3d69492ea81bd9bf328e9 to your computer and use it in GitHub Desktop.
Save DarkGhostHunter/033e85faceb3d69492ea81bd9bf328e9 to your computer and use it in GitHub Desktop.
A class that throttles it's target methods calls.
<?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