s3: expose retry/backoff constants via environment variables - #296
s3: expose retry/backoff constants via environment variables#296alliasgher wants to merge 2 commits into
Conversation
|
@mantissahz Please review the PR. |
There was a problem hiding this comment.
Pull request overview
Adds environment-based S3 retry tuning as the backupstore-side foundation for longhorn/longhorn#12155.
Changes:
- Adds retry-attempt and backoff environment overrides.
- Preserves defaults for invalid or missing values.
- Adds parsing-focused unit tests.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
s3/s3_service.go |
Defines and applies S3 retry overrides. |
s3/s3_service_retry_test.go |
Tests override parsing and fallback behavior. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| t.Setenv(EnvAWSRetryMaximumAttempts, tc.env) | ||
| if got := retryMaximumAttempts(); got != tc.want { | ||
| t.Fatalf("retryMaximumAttempts() = %d, want %d", got, tc.want) |
There was a problem hiding this comment.
Added in 21c2977 as TestRetryMaximumAttempts_AppliedToClient, covering both the backoff and non-backoff branches.
| if retryBackoff { | ||
| o.Retryer = retry.NewStandard(func(so *retry.StandardOptions) { | ||
| so.MaxAttempts = AWSRetryMaximumAttempts | ||
| so.MaxBackoff = AWSRetryMaximumBackoff | ||
| so.MaxAttempts = retryMaximumAttempts() | ||
| so.MaxBackoff = retryMaximumBackoff() |
There was a problem hiding this comment.
Confirmed and fixed in 21c2977. Reproduced with the vendored SDK: effective MaxAttempts was 5 with AWS_RETRY_MAXIMUM_ATTEMPTS=20, and 20 once o.RetryMaxAttempts is cleared.
mantissahz
left a comment
There was a problem hiding this comment.
LGTM
Hi @alliasgher,
Could you check if the Copilot's comment is valid and helpful?
|
@mantissahz It is valid, and it was a real bug. Fixed in I verified the mechanism rather than taking it on trust. Reproduced with the same SDK versions this repo vendors (s3 v1.97.3, config v1.32.13): So Copilot's first comment was right too: the existing tests only cover the env parsing helpers, so they passed either way. Added one asserting One caveat: |
| EnvAWSRetryMaxAttempts = "AWS_RETRY_MAX_ATTEMPTS" | ||
| // EnvAWSRetryMaximumAttempts overrides AWSRetryMaximumAttempts when set to a positive integer. | ||
| EnvAWSRetryMaximumAttempts = "AWS_RETRY_MAXIMUM_ATTEMPTS" | ||
| // EnvAWSRetryMaximumBackoff overrides AWSRetryMaximumBackoff when set to a Go duration string (e.g. "60s", "5m"). | ||
| EnvAWSRetryMaximumBackoff = "AWS_RETRY_MAXIMUM_BACKOFF" |
There was a problem hiding this comment.
Hi @alliasgher,
Could you try to add the new environment variables into this function setupS3Credential in the util/credential.go as AWSSecretKey?
Then we can allow users to set up the parameters in the Secret and pass them here.
The S3 backupstore service currently hardcodes three retry-related
constants (`AWSRetryMaxAttempts`, `AWSRetryMaximumAttempts`,
`AWSRetryMaximumBackoff`) so operators running against S3-compatible
endpoints with different latency/reliability characteristics have no way
to tune them without recompiling the binary.
Add three optional environment-variable overrides, following the
existing `AWS_ENDPOINTS` / `VIRTUAL_HOSTED_STYLE` env-var pattern:
* `AWS_RETRY_MAX_ATTEMPTS` — integer, overrides AWSRetryMaxAttempts
* `AWS_RETRY_MAXIMUM_ATTEMPTS` — integer, overrides AWSRetryMaximumAttempts
* `AWS_RETRY_MAXIMUM_BACKOFF` — Go duration (e.g. "60s", "5m"),
overrides AWSRetryMaximumBackoff
Empty / missing / malformed values silently fall back to the existing
defaults, so there's no behaviour change for users that don't set them.
Refs longhorn/longhorn#12155
Signed-off-by: Ali <alliasgher123@gmail.com>
Signed-off-by: Ali <ali@kscope.ai>
NewFromConfig calls finalizeRetryMaxAttempts after the option callback. When o.RetryMaxAttempts is nonzero, which it is because newInstance passes config.WithRetryMaxAttempts, it wraps the retryer in retry.AddWithMaxAttempts. That capped the custom retryer at AWS_RETRY_MAX_ATTEMPTS, so AWS_RETRY_MAXIMUM_ATTEMPTS had no effect above 5. Clear o.RetryMaxAttempts when installing the custom retryer. The non-backoff path is unchanged and still honours AWS_RETRY_MAX_ATTEMPTS. The existing tests only cover the env parsing helpers and passed either way, so add one that asserts Retryer.MaxAttempts() on the constructed client. Signed-off-by: alliasgher <alliasgher123@gmail.com>
21c2977 to
7fd2623
Compare
Which issue(s) this PR fixes:
Issue longhorn/longhorn#12155
What this PR does / why we need it:
The S3 backupstore service hardcodes three retry-related constants —
AWSRetryMaxAttempts(5),AWSRetryMaximumAttempts(10), andAWSRetryMaximumBackoff(300s). Operators running against S3-compatible endpoints with different latency or reliability characteristics have no way to tune them without recompiling.This PR adds three optional environment-variable overrides, following the existing
AWS_ENDPOINTS/VIRTUAL_HOSTED_STYLEenv-var pattern already used by this file:AWS_RETRY_MAX_ATTEMPTSAWSRetryMaxAttemptsAWS_RETRY_MAXIMUM_ATTEMPTSAWSRetryMaximumAttemptsAWS_RETRY_MAXIMUM_BACKOFF60s,5m)AWSRetryMaximumBackoffEmpty, missing, or malformed values silently fall back to the existing defaults, so no behaviour change for users that don't set them. Unit tests for each helper cover unset / valid / zero / negative / malformed cases.
Special notes for your reviewer:
longhorn/longhornexposing these as global settings / backup-target URL parameters per the issue description; figured it was cleaner to land the library-side primitive first.Additional documentation or context