Is your feature request related to a problem? Please describe.
We run a self-hosted HTTP remote cache (Bazel cache protocol, behind CloudFront) for a fairly large monorepo. Under CI load a small fraction of blob requests fail with transient 503s (CDN capacity ramp-up, S3 SlowDown, that kind of thing). We measured around 0.1-0.2% of requests during bursts.
moon currently gives up on the first error. For uploads that's mostly fine (the manifest is skipped and the next run rebuilds), but for downloads a single failed blob out of hundreds means the task ends up with a partial output set and fails hard with task_runner::missing_outputs. So a 0.1% transient error rate on the cache turns into red CI several times a day, even though a single retry would almost certainly have succeeded.
Example from our logs:
[WARN] moon_cache_storage::storage_backend Failed to retrieve blobs, will attempt to retrieve remaining from other storage backends storage="http-remote-cache" hash="43d4d1..." expected_count=265 actual_count=176 errors=["Failed to make HTTP request (503 Service Unavailable)."]
Error: task_runner::missing_outputs
Describe the solution you'd like
An opt-in retry setting on the remote cache client, off by default so current behavior doesn't change:
remote:
api: http
cache:
retries: 2
A short exponential backoff (honoring Retry-After when present) on 429/5xx responses would cover the common transient cases. I'd be happy if it only applied to the HTTP client at first.
Describe alternatives you've considered
- Retrying at the infrastructure level: CloudFront origin-group failover can't be used here because behaviors with PUT in AllowedMethods can't target origin groups, and reads/writes share paths.
- Making the failure softer instead of retrying: when a blob can't be fetched after retries, falling back to actually running the task instead of failing with
missing_outputs would also solve it. That might be worth doing regardless of retries, but it felt like a separate discussion.
- Wrapping moon with CI-level job retries, which works but re-runs entire jobs for a single lost 28-byte blob.
Additional context
Tested with moon 2.3.2. verifyIntegrity is enabled on our side; the failures above are plain HTTP errors, not integrity mismatches. If a PR is welcome for this I can give it a try.
Is your feature request related to a problem? Please describe.
We run a self-hosted HTTP remote cache (Bazel cache protocol, behind CloudFront) for a fairly large monorepo. Under CI load a small fraction of blob requests fail with transient 503s (CDN capacity ramp-up, S3 SlowDown, that kind of thing). We measured around 0.1-0.2% of requests during bursts.
moon currently gives up on the first error. For uploads that's mostly fine (the manifest is skipped and the next run rebuilds), but for downloads a single failed blob out of hundreds means the task ends up with a partial output set and fails hard with
task_runner::missing_outputs. So a 0.1% transient error rate on the cache turns into red CI several times a day, even though a single retry would almost certainly have succeeded.Example from our logs:
Describe the solution you'd like
An opt-in retry setting on the remote cache client, off by default so current behavior doesn't change:
A short exponential backoff (honoring Retry-After when present) on 429/5xx responses would cover the common transient cases. I'd be happy if it only applied to the HTTP client at first.
Describe alternatives you've considered
missing_outputswould also solve it. That might be worth doing regardless of retries, but it felt like a separate discussion.Additional context
Tested with moon 2.3.2.
verifyIntegrityis enabled on our side; the failures above are plain HTTP errors, not integrity mismatches. If a PR is welcome for this I can give it a try.