Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[5.4] RateLimiter bug fixes #18139

Merged
merged 2 commits into from
Feb 27, 2017
Merged

[5.4] RateLimiter bug fixes #18139

merged 2 commits into from
Feb 27, 2017

Conversation

laurencei
Copy link
Contributor

@laurencei laurencei commented Feb 27, 2017

There are 3x simultaneous bugs in the current RateLimiter. They currently cancel each other out so as whole the class is working - but individually none of the functions work as intended:

  1. tooManyAttempts()
    Currently if you have 5 attempts in the cache, and a $maxAttempts of 5 - this function returns false, when it should be true.

The reason this was not noticed until now is:

  1. hit()
    Sets the initial count to 1, then immediately increments it to 2. So the number of attempts is actually artificially increased by one.

The reason that might never have been noticed until now is:

  1. retriesLeft()

Currently the function does this:

return $attempts === 0 ? $maxAttempts : $maxAttempts - $attempts + 1;

Which you can see is actually artificially inflating the retriesLeft by 1. The reason is because, if you had the initial hit() wrong - the retriesLeft was also wrong. This PR reduces that code to just

return $maxAttempts - $attempts;

Because you dont need to adjust $attempts anymore - you can take it "as is".

This PR fixes all 3 bugs, yet should preserve the current behavior.

I've added an additional test for retiresLeft() to help prevent regressions.

$cache->shouldReceive('increment')->once()->with('key');
$rateLimiter = new RateLimiter($cache);

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

public function testRetriesLeftReturnsCorrectCount()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test seems kinda useless since the response is entirely mocked.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only mocked part is the caching of current attempts (set to 3).

The logic of retiresLeft() is not mocked. If you run that test now on the current unmodified code - it fails and returns 3.

It should be 2 - which this test detects.

@taylorotwell taylorotwell merged commit 91e81aa into laravel:5.4 Feb 27, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants