Skip to content

Commit

Permalink
[10.x] Custom RateLimiter increase (#50197)
Browse files Browse the repository at this point in the history
* Allow ratelimiter custom increments

* add test

* formatting

* formatting

* Revert formatting

* Formatting

* formatting

---------

Co-authored-by: Tim MacDonald <hello@timacdonald.me>
Co-authored-by: Taylor Otwell <taylor@laravel.com>
  • Loading branch information
3 people authored Feb 25, 2024
1 parent 7af1994 commit e45d424
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 6 deletions.
17 changes: 15 additions & 2 deletions src/Illuminate/Cache/RateLimiter.php
Original file line number Diff line number Diff line change
Expand Up @@ -105,13 +105,26 @@ public function tooManyAttempts($key, $maxAttempts)
}

/**
* Increment the counter for a given key for a given decay time.
* Increment (by 1) the counter for a given key for a given decay time.
*
* @param string $key
* @param int $decaySeconds
* @return int
*/
public function hit($key, $decaySeconds = 60)
{
return $this->increment($key, $decaySeconds);
}

/**
* Increment the counter for a given key for a given decay time by a given amount.
*
* @param string $key
* @param int $decaySeconds
* @param int $amount
* @return int
*/
public function increment($key, $decaySeconds = 60, $amount = 1)
{
$key = $this->cleanRateLimiterKey($key);

Expand All @@ -121,7 +134,7 @@ public function hit($key, $decaySeconds = 60)

$added = $this->cache->add($key, 0, $decaySeconds);

$hits = (int) $this->cache->increment($key);
$hits = (int) $this->cache->increment($key, $amount);

if (! $added && $hits == 1) {
$this->cache->put($key, 1, $decaySeconds);
Expand Down
19 changes: 15 additions & 4 deletions tests/Cache/CacheRateLimiterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,29 @@ public function testHitProperlyIncrementsAttemptCount()
$cache = m::mock(Cache::class);
$cache->shouldReceive('add')->once()->with('key:timer', m::type('int'), 1)->andReturn(true);
$cache->shouldReceive('add')->once()->with('key', 0, 1)->andReturn(true);
$cache->shouldReceive('increment')->once()->with('key')->andReturn(1);
$cache->shouldReceive('increment')->once()->with('key', 1)->andReturn(1);
$rateLimiter = new RateLimiter($cache);

$rateLimiter->hit('key', 1);
}

public function testIncrementProperlyIncrementsAttemptCount()
{
$cache = m::mock(Cache::class);
$cache->shouldReceive('add')->once()->with('key:timer', m::type('int'), 1)->andReturn(true);
$cache->shouldReceive('add')->once()->with('key', 0, 1)->andReturn(true);
$cache->shouldReceive('increment')->once()->with('key', 5)->andReturn(5);
$rateLimiter = new RateLimiter($cache);

$rateLimiter->increment('key', 1, 5);
}

public function testHitHasNoMemoryLeak()
{
$cache = m::mock(Cache::class);
$cache->shouldReceive('add')->once()->with('key:timer', m::type('int'), 1)->andReturn(true);
$cache->shouldReceive('add')->once()->with('key', 0, 1)->andReturn(false);
$cache->shouldReceive('increment')->once()->with('key')->andReturn(1);
$cache->shouldReceive('increment')->once()->with('key', 1)->andReturn(1);
$cache->shouldReceive('put')->once()->with('key', 1, 1);
$rateLimiter = new RateLimiter($cache);

Expand Down Expand Up @@ -83,7 +94,7 @@ public function testAttemptsCallbackReturnsTrue()
$cache->shouldReceive('get')->once()->with('key', 0)->andReturn(0);
$cache->shouldReceive('add')->once()->with('key:timer', m::type('int'), 1);
$cache->shouldReceive('add')->once()->with('key', 0, 1)->andReturns(1);
$cache->shouldReceive('increment')->once()->with('key')->andReturn(1);
$cache->shouldReceive('increment')->once()->with('key', 1)->andReturn(1);

$executed = false;

Expand All @@ -101,7 +112,7 @@ public function testAttemptsCallbackReturnsCallbackReturn()
$cache->shouldReceive('get')->times(6)->with('key', 0)->andReturn(0);
$cache->shouldReceive('add')->times(6)->with('key:timer', m::type('int'), 1);
$cache->shouldReceive('add')->times(6)->with('key', 0, 1)->andReturns(1);
$cache->shouldReceive('increment')->times(6)->with('key')->andReturn(1);
$cache->shouldReceive('increment')->times(6)->with('key', 1)->andReturn(1);

$rateLimiter = new RateLimiter($cache);

Expand Down

0 comments on commit e45d424

Please sign in to comment.