Skip to content

fix(scheduler): defuse cache-lookup drop-guard after claiming the map entry - #52

Open
b7r6 wants to merge 1 commit into
mainfrom
b7r6/cachelookup-scopeguard-stale-remove
Open

b7r6 wants to merge 1 commit into
mainfrom
b7r6/cachelookup-scopeguard-stale-remove

Conversation

@b7r6

@b7r6 b7r6 commented Oct 7, 2026 •

Copy link
Copy Markdown
Owner

What and why

Lane A stability fix from the findings catalog (see nativelink-findings-2026-10-05.csv
on the meta/findings-catalog-2026-10-05 branch), rebased onto OSS main
@bf4b3aa855. This fork PR exists to validate the change on CI that is
representative of upstream PR lanes (public read-only cache, same endpoints)
before any upstream submission.

How was this verified?

The branch carries its own regression tests (fails-without where the fix
class allows it — see the branch's test commits). This PR's purpose is the
full representative CI run; green here rehearses the exact checks an
upstream PR would face.

Risk

Fork-internal validation PR; nothing lands anywhere by merging this. The
underlying fix's risk assessment happens at upstream-submission time.

AI assistance

Agent-assisted pipeline (Claude) for rebase and PR mechanics under my
direction; the fix itself carries verification in its tests.

@b7r6
b7r6 force-pushed the b7r6/cachelookup-scopeguard-stale-remove branch 2 times, most recently from 794cdfb to 910ef34 Compare October 7, 2026 20:37
… entry

The inflight-dedup drop-guard in CacheLookupScheduler::add_action was bound
as `let _scope_guard = scope_guard;`, so it fired on *every* exit of the
spawn — including normal completion, after the spawn had already removed its
own entry and resolved the coalesced waiters.

A concurrent request for the same cacheable key, arriving in the window
between the leader's own `inflight_cache_checks.remove(...)` and the spawn's
exit (dropping the guard), inserts a fresh entry. The stale guard then
removes *that* entry, orphaning the second request: its oneshot sender is
dropped, surfacing a spurious "tx hung up" error to the client and forcing
a needless retry.

Fix: defuse the guard via `ScopeGuard::into_inner` the moment the cache
check returns. From that point every arm removes our own entry with no
intervening `.await` (no drop point), so defusing is leak-free and the guard
can no longer clobber a concurrent same-key re-insertion. The guard still
provides true drop-safety for the only window that matters: a spawn death
during the cache-store check, before we claim the entry.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@b7r6
b7r6 force-pushed the b7r6/cachelookup-scopeguard-stale-remove branch from 910ef34 to ef7f0ce Compare October 8, 2026 15:12
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