fix(overpass): retry a joined caller's admission on its own quota

A caller that joins a cold reservation no longer inherits another client's
RATE_LIMITED result. Once the rejected reservation is released it retries:
it either owns the next reservation and is admitted on its own quota, or joins
an admitted fetch. Adds a two-client regression (exhausted owner, available
joiner, exhausted joiner coalescing onto the admitted fetch).

Also drops the duplicate memory publication for a disk hit in the handler;
preflight already sets it, the handler only trims.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
Said TurkseverandClaude Opus 5.5 committed 2026-10-23 12:33:05 +01:00
1 parent bdf5899dda
commit 0c20ed9975
3 files changed
+59 -23

No files matched your search

+26 -19
View File
@@ -79,7 +79,9 @@ function writeOverpassDisk(cacheKey, payload) {
/**
* Resolve every cache/coalescing layer before admitting a request to the local
* upstream rate limiter. The injected limiter callback is invoked exactly once
* for a complete cache miss and never for memory, in-flight, or disk hits.
* for a complete cache miss and never for memory, in-flight, or disk hits. A
* caller that joined a reservation rejected by another client's limiter
* retries with its own limiter instead of inheriting that 429.
* Exported so the admission ordering can be tested without a Vite server.
*
* @param {object} options
@@ -103,25 +105,30 @@ async function resolveOverpassPreflight({
now = Date.now(),
cacheMs = OVERPASS_CACHE_MS,
}) {
const cached = memoryCache.get(cacheKey);
if (overpassPayloadIsData(cached) && now - cached.cachedAt <= cacheMs)
return { source: 'HIT', payload: cached };
for (;;) {
const cached = memoryCache.get(cacheKey);
if (overpassPayloadIsData(cached) && now - cached.cachedAt <= cacheMs)
return { source: 'HIT', payload: cached };
// Reserve synchronously before disk I/O. The owner retains the reservation
// through upstream admission, fetch and cache publication.
const request = coalesceProxyRequest(inFlight, cacheKey, async () => {
const disk = await readDisk();
if (overpassPayloadIsData(disk)) {
memoryCache.set(cacheKey, disk);
return { source: 'DISK', payload: disk };
}
if (!allowUpstream()) return { source: 'RATE_LIMITED', payload: null };
return { source: 'UPSTREAM', payload: await loadUpstream() };
});
const result = await request.promise;
return request.shared && result.source !== 'RATE_LIMITED'
? { ...result, source: 'INFLIGHT' }
: result;
// Reserve synchronously before disk I/O. The owner retains the reservation
// through its own upstream admission, fetch and cache publication.
const request = coalesceProxyRequest(inFlight, cacheKey, async () => {
const disk = await readDisk();
if (overpassPayloadIsData(disk)) {
memoryCache.set(cacheKey, disk);
return { source: 'DISK', payload: disk };
}
if (!allowUpstream()) return { source: 'RATE_LIMITED', payload: null };
return { source: 'UPSTREAM', payload: await loadUpstream() };
});
const result = await request.promise;
if (!request.shared) return result;
// The owner's quota rejection belongs to the owner's client. The rejected
// reservation is released before joiners resume, so retry and let this
// caller own the next reservation (or join an admitted one) on its quota.
if (result.source === 'RATE_LIMITED') continue;
return { ...result, source: 'INFLIGHT' };
}
}
/** Return only last-good Overpass data, regardless of its age. */