Skip to content

test(cache): cover a remote cache entry expiring between fetch and download - #959

Merged
wan9chi merged 1 commit into
mainfrom
claude/remote-cache-eviction-fix-f7afd6
Nov 7, 2026
Merged

wan9chi merged 1 commit into
mainfrom
claude/remote-cache-eviction-fix-f7afd6

Conversation

@wan9chi

@wan9chi wan9chi commented Nov 7, 2026 •

Copy link
Copy Markdown
Member

Motivation

A remote cache entry can expire after a fetch returns it but before its output archive is downloaded. The Worker then answers the download with 404 blob_missing. No case covered that race, and timing alone can't reproduce it without sleeps.

remote-cache-server expire-entry --before-download NUMBER makes the e2e backend's tap expire the entry when its blob is next requested, before it forwards the request. The client requests the blob only after the fetch's response, so the entry always expires between the two.

The new expired_after_fetch case uses it. The fetch returns exact [1], GET /blob/1 gets a 404, and the task reruns with remote cache download failed as the miss reason. That reason stays as it is: the fetch did find an entry that passed validation, and the same 404 also comes from a blob missing from the bucket while its entry is still live, which a plain "no previous cache entry found" would hide.

🤖 Generated with Claude Code


Note

Low Risk
Changes are confined to e2e test harness and remote-cache-server tooling; production remote-cache client behavior is unchanged.

Overview
Adds e2e coverage for when a remote cache fetch succeeds but the blob download gets 404 because the entry expired in between—a race that timing alone can't reproduce reliably.

remote-cache-server expire-entry --before-download NUMBER marks a blob so the test daemon's tap calls expireEntry on the next GET /blob/..., before forwarding—simulating retention expiring after the client has the fetch response but before it downloads the archive.

The new expired_after_fetch snapshot case seeds a cache entry, arms that mode, then runs vt run build again after a local cache clean. It expects POST /fetch 200 exact [1], GET /blob/1 404, a rerun with miss reason remote cache download failed, and --last-details showing the HTTP 404—not a plain "no entry" miss.

Reviewed by Cursor Bugbot for commit ede3a69. Bugbot is set up for automated code reviews on this repo. Configure here.

…wnload

`remote-cache-server expire-entry --before-download NUMBER` makes the tap
expire the entry when its blob is next requested, before it forwards the
request. The client requests the blob only after the fetch's response, so
the entry always expires between the two, without sleeps.

The `expired_after_fetch` case uses it: the fetch returns the entry, the
download gets a 404, and the task reruns with the failed download as the
miss reason.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Nov 7, 2026

Copy link
Copy Markdown

fspy benchmark

linux

dynamic/launch             change  +0.38%  [ -2.38% ..  +3.68%]  overhead   +56.37%
dynamic/access             change  +0.43%  [ -3.38% ..  +4.79%]  overhead   +18.67%
dynamic/access-relative    change  +0.31%  [ -2.71% ..  +2.38%]  overhead   +67.19%
dynamic/access-contended   change  +2.00%  [ -1.82% ..  +4.67%]  overhead   +33.50%
static/launch              change  +0.18%  [ -3.00% ..  +2.94%]  overhead  +198.74%
static/access              change  +0.23%  [ -0.67% ..  +1.00%]  overhead +1472.31%
static/access-relative     change  +0.15%  [ -1.03% ..  +0.84%]  overhead +1980.24%
static/access-contended    change  +0.32%  [ -0.81% ..  +1.31%]  overhead +2005.83%

macos

dynamic/launch             change  -0.10%  [ -4.82% ..  +4.38%]  overhead  +236.12%
dynamic/access             change  +0.00%  [ -8.57% .. +25.42%]  overhead    +2.46%
dynamic/access-relative    change  +1.95%  [ -7.69% .. +145.83%]  overhead  +248.60%
dynamic/access-contended   change  +1.41%  [ -9.04% .. +13.20%]  overhead    +2.92%

windows

dynamic/launch             change  -0.39%  [ -2.01% ..  +1.75%]  overhead   +26.14%
dynamic/access             change  +0.73%  [ -1.79% ..  +5.88%]  overhead    +1.91%
dynamic/access-relative    change  +0.00%  [ -5.19% .. +16.00%]  overhead    +1.57%
dynamic/access-contended   change  -0.52%  [ -2.73% ..  +1.06%]  overhead    +1.41%

@wan9chi
wan9chi merged commit ae97061 into main Nov 7, 2026
23 checks passed
@wan9chi
wan9chi deleted the claude/remote-cache-eviction-fix-f7afd6 branch November 7, 2026 11:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant