mirror of
https://github.com/dtzp555-max/ocp.git
synced 2026-07-21 21:15:09 +00:00
fix(server): drain F3 fallback queue immediately — invalidate F5 keychain cache before the serialized re-check
Follow-up to the F3/F5/F6 fix (independent-review observation). F5's 30s keychain TTL cache could make F3's post-refresh re-check see the stale (expiring) cached creds for up to ~30s, so a waiter admitted right after the prior real-HOME holder's claude refreshed the keychain would needlessly fall back to real HOME again instead of proceeding ISOLATED. Serialization safety was never at risk (still one real-HOME spawn at a time, no double-refresh); only the drain-to-fast-path optimization lagged. Fix: invalidateKeychainReadCache() clears the F5 TTL cache; resolveSpawnDecision() calls it under the fallback mutex, immediately before the re-check, so the admitted waiter reads FRESH keychain state and drains to the isolated fast path at once. The extra keychain read happens only on the rare real-HOME fallback path and only under the mutex (serialized, one at a time). Alignment: unchanged from the parent commit — proxy-internal keychain/HOME-isolation process logic, no cli.js analogue (cli.js citation DECLARED ABSENT, ALIGNMENT.md Rule 2), no endpoint/header/body, /health shape unchanged, OCP still never performs a refresh_token grant itself (#112). 249 tests pass. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+12
@@ -471,6 +471,10 @@ async function resolveSpawnDecision() {
|
||||
// piling every request into the real HOME.
|
||||
const release = await realHomeFallbackMutex.acquire();
|
||||
try {
|
||||
// Drop the 30s keychain TTL cache so the re-check reads FRESH keychain state — otherwise a
|
||||
// waiter admitted right after the prior holder's claude refreshed the token could still see the
|
||||
// stale (expiring) cached creds and needlessly fall back to real HOME again for up to ~30s.
|
||||
invalidateKeychainReadCache();
|
||||
const retry = resolveSpawnToken();
|
||||
if (retry) {
|
||||
release();
|
||||
@@ -1641,6 +1645,14 @@ function readKeychainCreds() {
|
||||
});
|
||||
}
|
||||
|
||||
// F3 drain helper: drop the F5 keychain TTL cache so the NEXT getOAuthCredentials() re-reads the
|
||||
// keychain from scratch. Called under the real-HOME fallback mutex just before the re-check, so a
|
||||
// waiter admitted after the prior holder's claude refreshed the keychain sees the FRESH token
|
||||
// immediately (and proceeds ISOLATED) instead of waiting out the ≤30s TTL on the stale creds.
|
||||
function invalidateKeychainReadCache() {
|
||||
_keychainCache.clear();
|
||||
}
|
||||
|
||||
function getOAuthCredentials() {
|
||||
// 1. Env var fallback — highest precedence for explicit overrides.
|
||||
if (process.env.CLAUDE_CODE_OAUTH_TOKEN) {
|
||||
|
||||
Reference in New Issue
Block a user