8000 [RateLimiter] Fix SlidingWindow calculation by Jeroeny · Pull Request #51592 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

Conversation

@Jeroeny
Copy link
Contributor
@Jeroeny Jeroeny commented Sep 7, 2023
Q A
Branch? 5.4
Bug fix? yes
New feature? no
Deprecations? no
Tickets Fix #40289
License MIT

Reopened #47557 but as a bugfix PR targeting 5.4 instead.

This implements LimiterInterface->reserve() for SlidingWindowLimiter. I'm not sure if the lack of implementation was due to time/scope or if it's actually not possible and my approach is incorrect. But I like to give it a try anyway. Perhaps @wouterj you could elaborate on that?

The calculation does the following:

  1. Calculate tokens to be released within this window. E.g. if 4 were used in the last window, at 50% into the current, 2 are still to be released.
  2. Calculate the time-per-token within the remainder of the window. If the requested tokens will be available before the end of the current window, return the time-per-token * needed-tokens.
  3. Otherwise return time-per-token of the regular interval * needed-tokens(-after the current window).

Some other things I've noticed in the RateLimiter:

  • FixedWindowLimiter uses a Window class, whereas SlidingWindowLimiter uses a SlidingWindow. Shouldn't the first have a FixedWindow class?
  • The Window class takes its $windowSize as argument, SlidingWindow does not. Perhaps the latter could also take this argument in this PR, since it's used in the calculation. But I guess those classes have to be backwards compatible.
  • SlidingWindow->getRetryAfter() is no longer used and could be deprecated in favor of calculateTimeForTokens. Making it more like the fixed window.

@Jeroeny
Copy link
Contributor Author
Jeroeny commented Sep 14, 2023

@wouterj @Nyholm I see you have some history in this component. Maybe one of you would be interested to review this fix?

Copy link
Member
@Nyholm Nyholm left a comment

Choose a reason for hiding this comment

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

Thank you for this PR.

This is a bit tricky part of the code base. I suggest some extra eyes to review this.
Can you please add some more test for the new calculateTimeForToken()?

I also have to ask you to target 6.4 since this is a new feature and not a bugfix. The feature is "Add SlidingWindowLimiter::reserve()".

return (int) floor($this->hitCountForLastWindow * (1 - $percentOfCurrentTimeFrame) + $this->hitCount);
}

public function getRetryAfter(): \DateTimeImmutable
Copy link
Member

Choose a reason for hiding this comment

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

You cannot remove public methods. That is a BC break.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

My bad, thought the @internal class allowed this.

@Jeroeny
Copy link
Contributor Author
Jeroeny commented Sep 18, 2023

Reopened as feature PR: #51676

@Jeroeny Jeroeny closed this Sep 18, 2023
fabpot added a commit that referenced this pull request Oct 1, 2023
…oeny)

This PR was squashed before being merged into the 6.4 branch.

Discussion
----------

[RateLimiter] Add SlidingWindowLimiter::reserve()

| Q             | A
| ------------- | ---
| Branch?       | 6.4
| Bug fix?      | yes
| New feature?  | yes
| Deprecations? | yes
| Tickets | Fix #40289, Fixes #46875
| License       | MIT

This implements `LimiterInterface->reserve()` for `SlidingWindowLimiter`. I'm not sure if the lack of implementation was due to time/scope or if it's actually not possible and my approach is incorrect. But I like to give it a try anyway. Perhaps `@wouterj` you could elaborate on that?

The calculation does the following:

1. Calculate tokens to be released within this window. E.g. if 4 were used in the last window, at 50% into the current, 2 are still to be released.
2. Calculate the time-per-token within the remainder of the window. If the requested tokens will be available before the end of the current window, return the time-per-token * needed-tokens.
3. Otherwise return time-per-token of the regular interval * needed-tokens(-after the current window).

This wasn't a [bugfix](#51592), so back to feature PR. I couldn't reopen #47557, So had to create this new PR.

Commits
-------

1b4a2df [RateLimiter] Add SlidingWindowLimiter::reserve()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@Nyholm Nyholm Nyholm requested changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

0