mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-10-05 19:28:25 +00:00
fix(blossom): re-check the token cache after winning the in-flight slot
The pre-insert cache look added in 6dc631e85d narrowed the single-flight
gap but didn't close it: a fast leader can insert, sign, cache and retire
its entry entirely between a straggler's cache read and its putIfAbsent,
so the straggler wins an empty map and signs a second time. That is the
intermittent `expected:<1> but was:<2>` in aFastSignerStillSharesOneSignature
failing main CI.
Check the cache again once this caller owns the slot. A leader always caches
before retiring its entry, so any token minted before the insert is visible
there; take it and give the slot back instead of re-signing.
Reproduced locally at round 2431 of 5000; two 5000-round runs pass with the fix.
This commit is contained in:
+11
@@ -129,6 +129,17 @@ class BlossomReadAuthTokenProvider(
|
||||
val fresh = CompletableDeferred<String?>()
|
||||
inFlight.putIfAbsent(host, fresh)?.let { return it }
|
||||
|
||||
// Third look, now that this caller owns the slot. The look above still leaves a
|
||||
// gap: a leader can insert, sign, cache and retire its entry entirely between
|
||||
// that read and the putIfAbsent, so the map is empty again and this caller wins
|
||||
// it. Any leader that retired before this insert cached first, so a token
|
||||
// present now is theirs — take it and give the slot back instead of re-signing.
|
||||
cachedHeader(host)?.let {
|
||||
inFlight.remove(host, fresh)
|
||||
fresh.complete(it)
|
||||
return fresh
|
||||
}
|
||||
|
||||
scope
|
||||
.launch {
|
||||
val header =
|
||||
|
||||
Reference in New Issue
Block a user