Skip to content

🐛 fix(usage): clear in-flight lock on a successful fetch#487

Open
gaborbernat wants to merge 1 commit into
sirmalloc:mainfrom
gaborbernat:fix/clear-usage-lock-on-success
Open

🐛 fix(usage): clear in-flight lock on a successful fetch#487
gaborbernat wants to merge 1 commit into
sirmalloc:mainfrom
gaborbernat:fix/clear-usage-lock-on-success

Conversation

@gaborbernat

Copy link
Copy Markdown

Switching Claude accounts could leave the usage widgets stuck on [Timeout] for up to 30 seconds even though the API was healthy and the new account would have fetched fine. 🔐 The trigger is the in-flight guard fetchUsageData writes before every API call: a usage.lock carrying { error: 'timeout', blockedUntil: now + LOCK_MAX_AGE }. On a successful fetch the cache is written and returned, but that pre-fetch lock is never removed, so it lingers for the full LOCK_MAX_AGE.

Inside that window any render that misses the file cache falls through to readActiveUsageLock and returns getStaleUsageOrError('timeout', …). An account switch is the clearest case: the fresh cache is rejected because the new token fails tokenHashMatches, the old account's cache is also rejected by fingerprint, and the leftover lock turns the result into { error: 'timeout' }. The label is misleading too, since usage.lock reads timeout after a fetch that actually succeeded.

The fix clears the lock once the successful response has been cached. ✨ Genuine error and rate-limit backoff locks are written on their own paths and stay untouched, so the existing "don't serve a mismatched account cache during an active lock" backoff behaviour is preserved.

Fixes #486

The pre-fetch usage.lock is written as a 'timeout' guard before the API
call but is never removed on success, so it lingers for LOCK_MAX_AGE. A
cache miss in that window (e.g. an account switch invalidating the token
fingerprint) then returns getStaleUsageOrError('timeout', ...), showing a
spurious [Timeout] while the API is healthy.

Clear the lock after a successful cache write. Genuine error and
rate-limit backoff locks are untouched.

Fixes sirmalloc#486
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.

Usage: pre-fetch lock not cleared on success → spurious [Timeout] after account switch

1 participant