fix(blossom): take a third cache look once the in-flight slot is held

BlossomReadAuthTokenProviderTest.aFastSignerStillSharesOneSignature still
fails about one run in three (round N: expected 1 signature, was 2), which
the pre-push hook turns into a hard block on every push.

The second cache look added in 6dc631e8 closes the leader-finished-early
window for callers that reach it after the leader retired its entry, but
not for a caller parked between that look and its own putIfAbsent: a
leader that starts after the caller's miss can sign, cache and retire in
that gap (a local key does it in microseconds), so the parked caller's
putIfAbsent then succeeds against an empty map and mints a second token.

Once the caller holds the in-flight slot, any earlier leader has already
cached, because a leader caches before it retires. So a cache hit taken
at that point is definitive: hand the cached token to ourselves and to
every follower already parked on our deferred, and retire the slot.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PguqnDbP2v11dtANs9xdxc
This commit is contained in:
Claude
2026-09-12 16:43:59 +00:00
parent 32f0c462bb
commit cfa6f72760
@@ -129,6 +129,20 @@ class BlossomReadAuthTokenProvider(
val fresh = CompletableDeferred<String?>()
inFlight.putIfAbsent(host, fresh)?.let { return it }
// Third look, taken while holding the [inFlight] slot. The second look above
// still leaves a window: a caller that missed the cache there can be parked
// before its `putIfAbsent` while a leader that started after it signs, caches
// and retires its own entry — a local key does all of that in microseconds —
// so the parked caller's `putIfAbsent` then succeeds against an empty map and
// mints a second signature. With the slot held, any earlier leader has already
// cached (it caches *before* retiring), so a hit here is definitive: hand the
// cached token to ourselves and to every follower that already joined [fresh].
cachedHeader(host)?.let { cached ->
inFlight.remove(host, fresh)
fresh.complete(cached)
return fresh
}
scope
.launch {
val header =