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

[11.x] Allow list of rate limiters without requiring unique keys #53177

Merged
merged 2 commits into from
Oct 16, 2024

Conversation

timacdonald
Copy link
Member

@timacdonald timacdonald commented Oct 15, 2024

This PR ensures that rate limiters specifying multiple limits will always have unique keys.

The issue.

RateLimiter::for('limiter-name', fn () => [
    Limit::perSecond(1),
    Limit::perMinute(30),
]);

This rate limiter will always fail. No request would ever get through. Zero. Nada.

This is because both limits share the same key. The docs specify that If you're assigning multiple rate limits segmented by identical by values, you should ensure that each by value is unique

Screenshot 2024-10-16 at 09 52 04

This is fine, but also can be something easily forgotten; bit of a footgun.

The improvement

This PR attempts to improve the situation by ensuring that when a list of limits has duplicate keys they are modified to be unique.

RateLimiter::for('limiter-name', fn () => [
    Limit::perSecond(1),
    Limit::perMinute(30)->by(Auth::user()),
    Limit::perDay(500),
]);

In this above example, the first and the last limits would have their key modified to be unique.

Although this is a breaking change, it only breaks in already broken situations, so I see this as an overall improvement.

I don't feel like we need to update the docs. This is just a fallback fix for those rare times it is held wrong.


fixes #53157

Copy link

Thanks for submitting a PR!

Note that draft PR's are not reviewed. If you would like a review, please mark your pull request as ready for review in the GitHub user interface.

Pull requests that are abandoned in draft may be closed due to inactivity.

@timacdonald timacdonald force-pushed the combined-throttles branch 2 times, most recently from 4958a8d to 7dcd17c Compare October 16, 2024 00:11
@timacdonald timacdonald changed the base branch from master to 11.x October 16, 2024 00:12
@timacdonald timacdonald changed the title [12.x] Allow list of rate limiters without requiring unique keys [11.x] Allow list of rate limiters without requiring unique keys Oct 16, 2024
@timacdonald timacdonald marked this pull request as ready for review October 16, 2024 01:08
@taylorotwell taylorotwell merged commit 9867436 into laravel:11.x Oct 16, 2024
23 of 31 checks passed
@timacdonald timacdonald deleted the combined-throttles branch October 16, 2024 21:50
@gcg
Copy link

gcg commented Oct 23, 2024

After deploying our app with laravel 11.29 (which this pr is a part of) today, all our users started getting rate limit errors for 40 minutes (until we discovered the problem). I temporarily downgraded and deployed which fixed our problem and will investigate further on what combination was the actual cause.

But i am leaving this clue here so if someone searches for rate limit and laravel 11.29 maybe they will find the issue faster.

edit#1: only grouped rate limits failed, which this pr also targets so i am 99% sure this is breaking some live apps.

update#2: probably my bad. missed in the docs that we need to uniquely name our by limits part. I will name them and test it again.
image

@NickSdot
Copy link
Contributor

@gcg wasn't this PR all about that you no longer need to give unique names?

@gcg
Copy link

gcg commented Oct 23, 2024

@gcg wasn't this PR all about that you no longer need to give unique names?

Still did not test ALL possible combinations but I was using the exact same example w/out giving unique names and after this PR, those 2 limiters that returns multiple limits in an array w/out unique names started failing all requests.

I will share more information but giving unique key names manually seems to be working and it's clearly documented so I am in the blame here :) I am reporting live here just in case it happens to someone else.

@timacdonald
Copy link
Member Author

Thanks for letting us know, @gcg.

Please let us know what you find out. My gut feeling is that your previous set up, sharing the same keys, was likely not working as expected even if it seemed to be working.

Keep me posted.

@timacdonald
Copy link
Member Author

And sorry for the troubles!

@gcg
Copy link

gcg commented Oct 24, 2024

Please let us know what you find out. My gut feeling is that your previous set up, sharing the same keys, was likely not working as expected even if it seemed to be working.

yeah, you are probably right. I had 2 limiters that returns list limits, one of them is so rarely used and the other route has it's own custom rate limits built in predating laravel mw, even if the ratelimiter didn't work before for that case, I probably didn't notice and only noticed once we started failing requests.

Keep me posted.

I redeployed rate limiters after uniquely naming everything and now it's back to normal.

And sorry for the troubles!

It's not your fault that I missed the warning in the documentation, as u stated, it wasn't probably working as it should from the beginning.

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.

the RateLimiter Limit::perSecond not working as expected for the queue jobs
4 participants