pi-lens
Version:
Real-time code feedback for pi — LSP, linters, formatters, type-checking, structural analysis & booboo
59 lines (58 loc) • 2.64 kB
JavaScript
/**
* Generic "only proceed if this token is >= the last-seen token for this
* key" guard, for per-key caches fed by concurrent, possibly-out-of-order
* writers.
*
* Same race class as #555 (`clients/lsp/client.ts`'s `isSupersededPush`
* guard on `publishDiagnostics`): pi-lens deliberately allows concurrent
* pipeline runs for the SAME file across DIFFERENT same-turn edits (dedupe
* key is `filePath + contentHash`, not just `filePath` — see
* `clients/runtime-tool-result.ts`). If an OLDER edit's pipeline is slower
* than a NEWER edit's pipeline, the older edit's write can land after the
* newer one and silently overwrite it — a per-key cache with no ordering
* check serves the stale result as "current" until some later write (if
* any) corrects it.
*
* This module extracts that guard shape into a small, reusable, non-
* diagnostics-specific primitive so a second (or third) call site with the
* same race doesn't need to re-derive or duplicate the check. `clients/lsp/
* client.ts`'s already-merged #555 fix is inline and deliberately left
* alone — this is additive, for new call sites (starting with
* `clients/widget-state.ts`'s `recordDiagnostics`).
*
* A `undefined` token means "no ordering information available" — the write
* is always allowed through and does not update the last-seen token (mirrors
* the existing, deliberate version-less-server tradeoff in the LSP client:
* callers that can't supply an ordering token aren't penalized).
*/
export class WriteOrderingGuard {
lastSeen = new Map();
/**
* Returns `true` if a write with `token` for `key` should proceed, and
* `false` if it's superseded (a write with a higher token for the same
* key was already recorded) and should be dropped.
*
* On `true` with a defined `token`, records it as the new last-seen value
* for `key` — including on a tie (a write whose token matches the last
* recorded one is not superseded, and re-recording the same token is a
* no-op either way). The very first write for a key always proceeds
* (nothing to compare against yet).
*/
shouldWrite(key, token) {
if (token === undefined)
return true;
const last = this.lastSeen.get(key);
if (last !== undefined && token < last)
return false;
this.lastSeen.set(key, token);
return true;
}
/** Drop tracked ordering state for `key` (e.g. on cache eviction). */
delete(key) {
this.lastSeen.delete(key);
}
/** Drop all tracked ordering state. */
clear() {
this.lastSeen.clear();
}
}