cache: Serve Range GET from disk when present #44

Merged
linus merged 1 commits from moss/cache-range-from-disk into develop 2026-09-07 11:37:06 -05:00
Collaborator

Why

Steam clients lean on Range requests. Cache hit/miss could look healthy while downloads still felt cold: a Range miss stripped Range for the upstream fetch (correct for full-object caching) but then wrote the full body back to the client as 200 instead of a 206 slice.

What

  • Serve Range GETs from an already-cached full object as local 206 (existing streamCachedResponse path) and count range_cache
  • On Range miss: still fetch/cache the full upstream object (Range stripped), but return the client's requested byte range as 206 and count range_upstream
  • /metrics emits range_cache / range_upstream (snake_case)
  • README operator note + metrics table row

Same cache stack; no second cache. Out of scope: HEAD (#31), partial-object write protocols.

Test

  • go test ./... (jumpbox; make not installed in non-interactive PATH)
  • New steamcache/range_test.go: Range HIT local 206 + no upstream re-fetch + metrics; Range MISS 206 + full object cached + metrics; /metrics text emission; focused streamCachedResponse 206/416

Risks

  • Clients that previously tolerated a full-body 200 on a Range miss now get a proper 206; that matches HTTP Range semantics and Steam expectations
  • BytesServed/Saved for Range HITs now count range bytes (not the full cached blob)

Rollback

Revert this PR / branch tip on develop.

Fixes #38

## Why Steam clients lean on Range requests. Cache hit/miss could look healthy while downloads still felt cold: a Range miss stripped Range for the upstream fetch (correct for full-object caching) but then wrote the **full** body back to the client as 200 instead of a 206 slice. ## What - Serve Range GETs from an already-cached full object as local 206 (existing `streamCachedResponse` path) and count **`range_cache`** - On Range miss: still fetch/cache the full upstream object (Range stripped), but return the client's requested byte range as **206** and count **`range_upstream`** - `/metrics` emits `range_cache` / `range_upstream` (snake_case) - README operator note + metrics table row Same cache stack; no second cache. Out of scope: HEAD (#31), partial-object write protocols. ## Test - `go test ./...` (jumpbox; `make` not installed in non-interactive PATH) - New `steamcache/range_test.go`: Range HIT local 206 + no upstream re-fetch + metrics; Range MISS 206 + full object cached + metrics; `/metrics` text emission; focused `streamCachedResponse` 206/416 ## Risks - Clients that previously tolerated a full-body 200 on a Range miss now get a proper 206; that matches HTTP Range semantics and Steam expectations - BytesServed/Saved for Range HITs now count range bytes (not the full cached blob) ## Rollback Revert this PR / branch tip on `develop`. Fixes #38
eva was assigned by moss 2026-09-07 11:33:08 -05:00
moss added 1 commit 2026-09-07 11:33:09 -05:00
cache: Serve Range GET from disk when present
CI / vulncheck (pull_request) Successful in 15s
CI / check-and-test (pull_request) Successful in 41s
ac2d36f1ad
Steam clients lean on Range requests. Hit/miss looked fine while downloads
still felt cold when a Range miss returned the full upstream body as 200.

Add range_cache / range_upstream metrics. HIT path already sliced 206 from
the cached full object; count range_cache there. On MISS, keep stripping
Range for the upstream fetch (full object still cached) but serve the
client's requested slice as 206 and count range_upstream.

Tests in steamcache/range_test.go cover Range HIT (local, no upstream),
Range MISS (206 + full object cached), and /metrics emission.
moss requested review from eva 2026-09-07 11:33:09 -05:00
linus merged commit a500f51f17 into develop 2026-09-07 11:37:06 -05:00
linus deleted branch moss/cache-range-from-disk 2026-09-07 11:37:06 -05:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: s1d3sw1ped/steamcache2#44