Repository navigation
middleware: encode fractional Retry-After delays conservatively - #1206
Open
sergioperezcheco wants to merge 1 commit into
Open
sergioperezcheco wants to merge 1 commit into
sergioperezcheco wants to merge 1 commit into
Conversation
Signed-off-by: sergioperezcheco <checo520@outlook.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
ThrottleWithOptstruncates the duration returned byRetryAfterFnwhen encodingRetry-After. A 500ms delay is sent as0, and a 1.5s delay as1, asking clients to retry before the callback's delay has elapsed. Negative durations can produce a negative delay-seconds value.Change
Encode positive durations using integer division and a remainder, rounding fractional seconds up. Clamp negative durations to
0. This avoids floating-point conversion, platform-dependentintconversion, and adding to a duration before division, so the duration limits are handled without overflow. Zero and whole-second delays keep their existing values; a nil callback still omits the header.RFC 9110 §10.2.3 defines delay-seconds as a non-negative decimal integer. Rounding up is a conservative encoding choice, not a rounding rule mandated by the RFC.
The new regression tests exercise the public middleware through HTTP requests and handler calls. They cover capacity rejection, cancellation, backlog timeout, duration boundaries, and a nil callback, and verify that accepted HTTP requests still succeed without
Retry-After.This is a duration-encoding fix, not a rewrite of the existing throttle tests or a claim to fix #608. #474 introduced the callback API; #1194 and #1150 separately improve the existing tests. This change leaves
middleware/throttle_test.gountouched.Validation
On Go 1.26.4 / macOS arm64:
go test -p 1 -timeout 60s ./middleware -run 'TestThrottle(RetryAfter.*Duration|NoRetryAfterCallback)' -count=10 -vpasses.go test -p 1 -race -count=1 -timeout 120s ./...passes in independent parent verification. The new worktree uses the same base commit and byte-identical production/test files; this full race run was reused, not repeated.go test -p 1 -timeout 60s ./middleware -run TestThrottle -count=1andgo vet -p 1 ./middlewarepass.go vet -p 1 ./..., gofmt, goimports,git diff --check, and incremental staticcheck pass.The Linux/Windows and other Go-version CI matrix has not been run locally.
Implemented with AI assistance through Hermes Agent, with independent parent regression and full-module race verification. The positive-fraction rounding and negative-duration clamp are proposed behavior changes, not previously approved maintainer policy.