Skip to content

RetryAfter metadata in FixedWindowRateLimiter returns time to next window - #124478

Merged
VSadov merged 1 commit into
dotnet:mainfrom
asbjornvad:#92557-RetryAfter_Ratelimiting
Apr 17, 2026
Merged

VSadov merged 1 commit into
dotnet:mainfrom
asbjornvad:#92557-RetryAfter_Ratelimiting

Conversation

@asbjornvad

@asbjornvad asbjornvad commented Feb 16, 2026 •

Copy link
Copy Markdown
Contributor

This solves the issue of wrongly returned RetryAfter value, however only in the FixedWindowRateLimiter.
The queue is not taken into consideration in this implementation.

#92557

Copilot AI review requested due to automatic review settings February 16, 2026 20:26
@dotnet-policy-service dotnet-policy-service Bot added the community-contribution Indicates that the PR has been added by a community member label Feb 16, 2026
@asbjornvad

Copy link
Copy Markdown
Contributor Author

@dotnet-policy-service agree

@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @agocke, @VSadov
See info in area-owners.md if you want to be subscribed.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR attempts to fix issue #92557 where the FixedWindowRateLimiter incorrectly returns the full window duration as the Retry-After value instead of the remaining time until the next window. The implementation changes the CreateFailedWindowLease method to calculate the remaining time by subtracting the elapsed time from the window duration.

Changes:

  • Modified CreateFailedWindowLease to calculate remaining time instead of returning static window multiples
  • Added a test-injectable function field to control elapsed time behavior for testing
  • Updated test assertions to reflect the new expected behavior
  • Added a test helper method to manipulate elapsed time in tests

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 12 comments.

File Description
src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/FixedWindowRateLimiter.cs Adds injectable getElapsedTime function field; reimplements CreateFailedWindowLease to calculate remaining window time; comments out original queue-aware implementation
src/libraries/System.Threading.RateLimiting/tests/FixedWindowRateLimiterTests.cs Adds SetElapsedTime helper for testing; updates test expectations; adds calls to set elapsed time to 0 in multiple tests

Comment thread src/libraries/System.Threading.RateLimiting/tests/FixedWindowRateLimiterTests.cs Outdated
Comment thread src/libraries/System.Threading.RateLimiting/tests/FixedWindowRateLimiterTests.cs Outdated
Comment thread src/libraries/System.Threading.RateLimiting/tests/FixedWindowRateLimiterTests.cs Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

@asbjornvad
asbjornvad force-pushed the #92557-RetryAfter_Ratelimiting branch from af257cb to eced7f5 Compare March 1, 2026 15:14
@asbjornvad asbjornvad changed the title Initial overview of how the RetryAfter metadata should be set and tested RetryAfter metadata in FixedWindowRateLimiter returns time to next window Mar 1, 2026
@asbjornvad
asbjornvad marked this pull request as ready for review March 1, 2026 16:57
Copilot AI review requested due to automatic review settings March 1, 2026 16:57

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

@JulieLeeMSFT

Copy link
Copy Markdown
Member

@VSadov, please review this community PR.

@VSadov

VSadov commented Apr 15, 2026

Copy link
Copy Markdown
Member

I am looking. Not very familiar with the area, so may need some time to understand the change. It does not look too big though.

@VSadov

VSadov commented Apr 15, 2026

Copy link
Copy Markdown
Member

The change overall looks good to me, I just had a question about use of Interlocked.Read.

@VSadov

VSadov commented Apr 15, 2026

Copy link
Copy Markdown
Member

Regarding the queue: In my changes the thinking is that you are always told when the window resets. If there is a queue attached then you might end in the queue after waiting the RetryAfter value. This is different from the old way, where the returned value represented when the window + queue window(s) would be over.

I agree with this.
Considering permits count and queue length would just result in overestimate of minimum wait time without any additional guarantees.

Copilot AI review requested due to automatic review settings April 16, 2026 20:05
@asbjornvad
asbjornvad force-pushed the #92557-RetryAfter_Ratelimiting branch from 361f6a6 to da83766 Compare April 16, 2026 20:05

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

…xt window.

This commit solves the issue of wrongly returned RetryAfter value in the FixedWindowRateLimiter. It now returns the time to window refresh.
It includes tests to verify that the RetryAfter value is correct when the window has not yet elapsed, and when it has elapsed but has not been refreshed.
Changed Interlocked.Read to Volatile.Read, since the objective of the read was to avoid torn longs on 32 bit.
Added Volatile.Write when updating _lastReplenishmentTick.

The queue is not taken into consideration in this implementation and does not cover other RateLimiters that may have RetryAfter metadata.
@asbjornvad
asbjornvad force-pushed the #92557-RetryAfter_Ratelimiting branch from da83766 to 4d76805 Compare April 16, 2026 20:22

@VSadov VSadov left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM. Thanks!

@VSadov
VSadov enabled auto-merge (squash) April 17, 2026 07:20
@asbjornvad

Copy link
Copy Markdown
Contributor Author

Seems like the Build Analysis is stalled due to failed builds.

@VSadov

VSadov commented Apr 17, 2026

Copy link
Copy Markdown
Member

/ba-g build analysis stalled, all failures are known

@VSadov
VSadov merged commit 23e090b into dotnet:main Apr 17, 2026
91 of 96 checks passed
@asbjornvad
asbjornvad deleted the #92557-RetryAfter_Ratelimiting branch April 28, 2026 16:35
@github-actions github-actions Bot locked and limited conversation to collaborators May 29, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-System.Threading community-contribution Indicates that the PR has been added by a community member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants