@struktoai/mirage-core
Version:
A Unified Virtual Filesystem For AI Agents
55 lines • 2.8 kB
TypeScript
export type Stamp = readonly [epoch: number, key: number];
/**
* The invalidations a cache writer checks before it installs.
*
* A writer holds bytes it read earlier; an invalidation that lands between
* the read and the install makes them stale even though the writer was
* granted its turn after it. The writer takes a stamp before it waits and
* compares it before it installs.
*
* The RAM store holds a per-key lock only for its in-memory install,
* never across hashing or backend I/O. A free lock admits its writer
* without suspending on both hosts; a queued writer checks its stamp
* after acquiring the lock. Redis holds no client-side key lock: it
* sends atomic writes to the server and checks after acquiring its
* client (an await on TypeScript, synchronous on Python). The guard
* tracks local invalidations, not writes by other Redis clients.
*
* Two counters, because invalidations have different reaches. The
* store-wide epoch answers `clear`. The per-key counter answers a removal
* of one key and a prefix eviction, so a large fill is not thrown away
* because an unrelated key or folder was dropped. A prefix eviction can
* name its victims although a fill in flight has no entry yet: every
* writer registers here in `enter` before it waits. Per-key counters
* exist only while a writer for that key is in flight, which bounds the
* map by concurrent writers, not by every key ever removed.
*/
export declare class Invalidation {
private epoch;
private readonly keys;
private readonly writers;
/** Register a writer for `key` and take its stamp. */
enter(key: string): Stamp;
/** Unregister a writer for `key`; the last one out drops the key's counter. */
leave(key: string): void;
/** Whether an invalidation reached `key` since `stamp`. */
stale(key: string, stamp: Stamp): boolean;
/** Record a removal of `key` for the writers in flight on it. */
invalidate(key: string): void;
/**
* Record a prefix eviction for the writers in flight under it, matched
* as the stores match it (`startsWith`), sparing the excluded roots.
*/
invalidatePrefix(prefix: string, excluded?: readonly string[]): void;
/** Record an invalidation whose victims cannot be enumerated. */
invalidateAll(): void;
}
/**
* Track a fill's keys until it completes, fails or is cancelled.
*
* The callback starts without a yield, before any lock/client wait. Call
* its predicate immediately before each install or retry. Unknown keys
* are not live, and duplicate keys count as one writer.
*/
export declare function withFillGuard(invalidation: Invalidation, keys: Iterable<string>, fill: (isLive: (key: string) => boolean) => Promise<void>): Promise<void>;
//# sourceMappingURL=invalidation.d.ts.map