@openlimiter/core 2.0.4 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/acquire/codex-app-server.d.ts +1 -1
- package/dist/acquire/coordination.d.ts +11 -2
- package/dist/acquire/coordination.d.ts.map +1 -1
- package/dist/acquire/coordination.js +48 -6
- package/dist/acquire/coordination.js.map +1 -1
- package/dist/acquire/identity.d.ts +1 -1
- package/dist/acquire/identity.js +1 -1
- package/dist/cache.d.ts +13 -2
- package/dist/cache.d.ts.map +1 -1
- package/dist/cache.js +135 -64
- package/dist/cache.js.map +1 -1
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +18 -9
- package/dist/collection.js.map +1 -1
- package/dist/contracts/claude-presentation.json +12 -3
- package/dist/data-rules.d.ts +2 -0
- package/dist/data-rules.d.ts.map +1 -1
- package/dist/data-rules.js +19 -0
- package/dist/data-rules.js.map +1 -1
- package/dist/merge.d.ts.map +1 -1
- package/dist/merge.js +16 -4
- package/dist/merge.js.map +1 -1
- package/dist/policy.d.ts.map +1 -1
- package/dist/policy.js +3 -1
- package/dist/policy.js.map +1 -1
- package/dist/provider-presentation.d.ts +3 -3
- package/dist/provider-presentation.d.ts.map +1 -1
- package/dist/provider-presentation.js +30 -7
- package/dist/provider-presentation.js.map +1 -1
- package/dist/types.d.ts +1 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -4,7 +4,7 @@ export declare const MAX_CODEX_APP_SERVER_OUTPUT_BYTES = 1048576;
|
|
|
4
4
|
export declare const CODEX_APP_SERVER_CLIENT_INFO: {
|
|
5
5
|
readonly name: "openlimiter";
|
|
6
6
|
readonly title: "OpenLimiter";
|
|
7
|
-
readonly version: "2.
|
|
7
|
+
readonly version: "2.1.1";
|
|
8
8
|
};
|
|
9
9
|
export type CodexRateLimitsReadResult = {
|
|
10
10
|
readonly ok: true;
|
|
@@ -116,6 +116,15 @@ export declare const REFRESH_SPAWN_FAILURE_NAME = "openlimiter-refresh-spawn.jso
|
|
|
116
116
|
export declare function recordRefreshSpawnFailure(directory: string, now: string): Promise<void>;
|
|
117
117
|
/** When the last background refresh failed to start, if one did. */
|
|
118
118
|
export declare function readRefreshSpawnFailure(directory?: string): Promise<string | null>;
|
|
119
|
+
/**
|
|
120
|
+
* How long one start holds off the next.
|
|
121
|
+
*
|
|
122
|
+
* A child left suspended (its parent killed mid spawn on Windows) never runs,
|
|
123
|
+
* so it never takes the refresh lock, and the lock alone would let every
|
|
124
|
+
* render start one more. This bound makes it one start per window at most,
|
|
125
|
+
* whatever became of the child.
|
|
126
|
+
*/
|
|
127
|
+
export declare const REFRESH_START_INTERVAL_MILLISECONDS = 120000;
|
|
119
128
|
/** Forget it, which a refresh that actually ran is the proof of. */
|
|
120
129
|
export declare function clearRefreshSpawnFailure(directory?: string): Promise<void>;
|
|
121
130
|
export interface DetachedSpawn {
|
|
@@ -147,8 +156,8 @@ export type SpawnRefreshResult = {
|
|
|
147
156
|
/**
|
|
148
157
|
* Start a refresh behind the caller, and never wait for it.
|
|
149
158
|
*
|
|
150
|
-
* Everything expensive happens in the child. This function creates one
|
|
151
|
-
*
|
|
159
|
+
* Everything expensive happens in the child. This function creates one start
|
|
160
|
+
* token and hands the operating system a detached process, so the render that
|
|
152
161
|
* called it returns in the time a file create takes. A failure to spawn is
|
|
153
162
|
* reported and never thrown: a status line that cannot start a refresh still
|
|
154
163
|
* has to draw the bars it already has.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"coordination.d.ts","sourceRoot":"","sources":["../../src/acquire/coordination.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAG5D;;;;;;GAMG;AACH,eAAO,MAAM,2BAA2B,KAAK,CAAC;AAE9C,+EAA+E;AAC/E,eAAO,MAAM,iBAAiB,6BAA6B,CAAC;AAE5D;;;;;;GAMG;AACH,eAAO,MAAM,mCAAmC,QAAS,CAAC;AAE1D;;;;;;;;;;GAUG;AACH,eAAO,MAAM,+BAA+B,QAAS,CAAC;AAYtD,+EAA+E;AAC/E,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,SAAS,QAAQ,EAAE,GAC7B,MAAM,GAAG,IAAI,CAQf;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,SAAS,EAAE,SAAS,QAAQ,EAAE,EAC9B,GAAG,EAAE,MAAM,GACV,MAAM,GAAG,IAAI,CAKf;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,SAAS,QAAQ,EAAE,EAC9B,MAAM,EAAE,cAAc,EACtB,GAAG,EAAE,MAAM,EACX,aAAa,SAA4B,GACxC,OAAO,CAYT;AAED,qEAAqE;AACrE,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,SAAS,QAAQ,EAAE,EAC9B,GAAG,EAAE,MAAM,EACX,aAAa,SAA4B,GACxC,OAAO,CAET;AAED,+DAA+D;AAC/D,wBAAgB,UAAU,CACxB,SAAS,EAAE,SAAS,QAAQ,EAAE,EAC9B,MAAM,EAAE,cAAc,GACrB,QAAQ,EAAE,CAEZ;AAED,MAAM,MAAM,eAAe,GACvB;IAAE,OAAO,EAAE,IAAI,CAAA;CAAE,GACjB;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,OAAO,GAAG,iBAAiB,CAAA;CAAE,CAAC;AAE5D;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,SAAS,QAAQ,EAAE,EAC9B,GAAG,EAAE,MAAM,EACX,YAAY,SAA8B,GACzC,eAAe,CAcjB;AAID;;;;;;;GAOG;AACH,wBAAsB,eAAe,CACnC,SAAS,SAA0B,EACnC,eAAe,SAAa,EAC5B,IAAI,SAAoB,GACvB,OAAO,CAAC,OAAO,CAAC,CAWlB;AAED,MAAM,WAAW,iBAAiB;IAChC,+EAA+E;IAC/E,QAAQ,CAAC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC;;;;;;OAMG;IACH,QAAQ,CAAC,UAAU,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;CAC7C;AAED,MAAM,MAAM,iBAAiB,GACzB,CAAC;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG,iBAAiB,CAAC,GAClC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,GAAG,aAAa,CAAA;CAAE,CAAC;AAElD;;;;;;;;GAQG;AACH,wBAAsB,kBAAkB,CACtC,SAAS,SAA0B,EACnC,eAAe,SAAa,EAC5B,IAAI,SAAoB,GACvB,OAAO,CAAC,iBAAiB,CAAC,CAmE5B;AAID,sEAAsE;AACtE,eAAO,MAAM,0BAA0B,mCAAmC,CAAC;AAE3E;;;;;;;;;GASG;AACH,wBAAsB,yBAAyB,CAC7C,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,IAAI,CAAC,CAKf;
|
|
1
|
+
{"version":3,"file":"coordination.d.ts","sourceRoot":"","sources":["../../src/acquire/coordination.ts"],"names":[],"mappings":"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"}
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* never waits for the network; the next render shows what the refresh found.
|
|
14
14
|
*/
|
|
15
15
|
import { randomUUID } from "node:crypto";
|
|
16
|
-
import { lstat, open, readFile, unlink, utimes } from "node:fs/promises";
|
|
16
|
+
import { lstat, open, readdir, readFile, unlink, utimes, writeFile } from "node:fs/promises";
|
|
17
17
|
import path from "node:path";
|
|
18
18
|
import { prepareStateDirectory, readJsonFileSafely, resolveStateDirectory, writeFileAtomically } from "../cache.js";
|
|
19
19
|
import { canonicalJson } from "../normalizer.js";
|
|
@@ -262,9 +262,9 @@ export const REFRESH_SPAWN_FAILURE_NAME = "openlimiter-refresh-spawn.json";
|
|
|
262
262
|
export async function recordRefreshSpawnFailure(directory, now) {
|
|
263
263
|
await writeFileAtomically(path.join(directory, REFRESH_SPAWN_FAILURE_NAME), canonicalJson({ at: now, version: 1 })).catch(() => undefined);
|
|
264
264
|
}
|
|
265
|
-
/**
|
|
266
|
-
|
|
267
|
-
const document = await readJsonFileSafely(path.join(directory,
|
|
265
|
+
/** The time a small `{ at, version }` record in the state directory holds. */
|
|
266
|
+
async function readRecordedAt(directory, name) {
|
|
267
|
+
const document = await readJsonFileSafely(path.join(directory, name), 4_096);
|
|
268
268
|
if (!document.ok)
|
|
269
269
|
return null;
|
|
270
270
|
const value = document.value;
|
|
@@ -273,6 +273,34 @@ export async function readRefreshSpawnFailure(directory = resolveStateDirectory(
|
|
|
273
273
|
const at = value["at"];
|
|
274
274
|
return typeof at === "string" && Number.isFinite(Date.parse(at)) ? at : null;
|
|
275
275
|
}
|
|
276
|
+
/** When the last background refresh failed to start, if one did. */
|
|
277
|
+
export async function readRefreshSpawnFailure(directory = resolveStateDirectory()) {
|
|
278
|
+
return readRecordedAt(directory, REFRESH_SPAWN_FAILURE_NAME);
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* How long one start holds off the next.
|
|
282
|
+
*
|
|
283
|
+
* A child left suspended (its parent killed mid spawn on Windows) never runs,
|
|
284
|
+
* so it never takes the refresh lock, and the lock alone would let every
|
|
285
|
+
* render start one more. This bound makes it one start per window at most,
|
|
286
|
+
* whatever became of the child.
|
|
287
|
+
*/
|
|
288
|
+
export const REFRESH_START_INTERVAL_MILLISECONDS = 120_000;
|
|
289
|
+
/** The empty file whose exclusive creation reserves one start window. */
|
|
290
|
+
function startTokenName(window) {
|
|
291
|
+
return `openlimiter-refresh-start-${window}.token`;
|
|
292
|
+
}
|
|
293
|
+
/* Tokens of windows more than two behind hold nothing back. A token only two
|
|
294
|
+
behind stays, so a render whose clock runs slightly late cannot create it
|
|
295
|
+
again after a faster clock has moved on. */
|
|
296
|
+
async function removeOldStartTokens(directory, window) {
|
|
297
|
+
for (const name of await readdir(directory).catch(() => [])) {
|
|
298
|
+
const match = /^openlimiter-refresh-start-(\d+)\.token$/u.exec(name);
|
|
299
|
+
if (match !== null && window - Number(match[1]) > 2) {
|
|
300
|
+
await unlink(path.join(directory, name)).catch(() => undefined);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
276
304
|
/** Forget it, which a refresh that actually ran is the proof of. */
|
|
277
305
|
export async function clearRefreshSpawnFailure(directory = resolveStateDirectory()) {
|
|
278
306
|
await unlink(path.join(directory, REFRESH_SPAWN_FAILURE_NAME)).catch(() => undefined);
|
|
@@ -280,8 +308,8 @@ export async function clearRefreshSpawnFailure(directory = resolveStateDirectory
|
|
|
280
308
|
/**
|
|
281
309
|
* Start a refresh behind the caller, and never wait for it.
|
|
282
310
|
*
|
|
283
|
-
* Everything expensive happens in the child. This function creates one
|
|
284
|
-
*
|
|
311
|
+
* Everything expensive happens in the child. This function creates one start
|
|
312
|
+
* token and hands the operating system a detached process, so the render that
|
|
285
313
|
* called it returns in the time a file create takes. A failure to spawn is
|
|
286
314
|
* reported and never thrown: a status line that cannot start a refresh still
|
|
287
315
|
* has to draw the bars it already has.
|
|
@@ -301,8 +329,22 @@ export async function spawnDetachedRefresh(options) {
|
|
|
301
329
|
if (await refreshLockHeld(directory)) {
|
|
302
330
|
return { spawned: false, reason: "already_running" };
|
|
303
331
|
}
|
|
332
|
+
const window = Math.floor(Date.parse(options.now) / REFRESH_START_INTERVAL_MILLISECONDS);
|
|
304
333
|
try {
|
|
305
334
|
await prepareStateDirectory(directory);
|
|
335
|
+
/* Exclusive creation is the decision: the operating system lets exactly
|
|
336
|
+
one render, across every process, create this window's token, and only
|
|
337
|
+
that render spawns. Never best effort, so a start that could not be
|
|
338
|
+
reserved is not made and no child escapes the bound. */
|
|
339
|
+
try {
|
|
340
|
+
await writeFile(path.join(directory, startTokenName(window)), "", { flag: "wx", mode: 0o600 });
|
|
341
|
+
}
|
|
342
|
+
catch (error) {
|
|
343
|
+
if (errorCode(error) === "EEXIST")
|
|
344
|
+
return { spawned: false, reason: "already_running" };
|
|
345
|
+
throw error;
|
|
346
|
+
}
|
|
347
|
+
await removeOldStartTokens(directory, window);
|
|
306
348
|
options.spawn(options.nodeExecutable, [options.openLimiterScript, "refresh", "--detached"], {
|
|
307
349
|
cwd: directory,
|
|
308
350
|
onError: () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"coordination.js","sourceRoot":"","sources":["../../src/acquire/coordination.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"coordination.js","sourceRoot":"","sources":["../../src/acquire/coordination.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* package's own version, so the constant cannot drift.
|
|
15
15
|
*/
|
|
16
16
|
import type { ProviderCode } from "../types.js";
|
|
17
|
-
export declare const ACQUISITION_CLIENT_VERSION = "2.
|
|
17
|
+
export declare const ACQUISITION_CLIENT_VERSION = "2.1.1";
|
|
18
18
|
/** The only user agent any acquisition request may carry. */
|
|
19
19
|
export declare const OPENLIMITER_USER_AGENT: string;
|
|
20
20
|
/** Mirrors provider_detection::opaque_account_id, including the zero separator. */
|
package/dist/acquire/identity.js
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
*/
|
|
16
16
|
/** The published version this build identifies as. */
|
|
17
17
|
import { createHash } from "node:crypto";
|
|
18
|
-
export const ACQUISITION_CLIENT_VERSION = "2.
|
|
18
|
+
export const ACQUISITION_CLIENT_VERSION = "2.1.1";
|
|
19
19
|
/** The only user agent any acquisition request may carry. */
|
|
20
20
|
export const OPENLIMITER_USER_AGENT = "OpenLimiter/" + ACQUISITION_CLIENT_VERSION + " (+https://openlimiter.com)";
|
|
21
21
|
/** Mirrors provider_detection::opaque_account_id, including the zero separator. */
|
package/dist/cache.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ export { freshnessPolicy } from "./data-rules.js";
|
|
|
2
2
|
import { type CacheState, type CacheSuppression, type CollectionReport } from "./collection.js";
|
|
3
3
|
import type { ProviderCode, Snapshot } from "./types.js";
|
|
4
4
|
export declare const CACHE_FILE_NAME = "openlimiter-cache.json";
|
|
5
|
+
export declare const AUTHORITATIVE_CACHE_FILE_NAME = "openlimiter-authoritative.json";
|
|
5
6
|
export declare const MAX_POLICY_TIMESTAMP = 253402300799999;
|
|
6
7
|
/** Pure policy shared with the desktop contract. All instants are UTC. */
|
|
7
8
|
export declare function retryPolicy(input: {
|
|
@@ -42,7 +43,7 @@ export declare const CACHE_LOCK_NAME = "openlimiter.lock";
|
|
|
42
43
|
/** Largest JSON document this package will read into memory. */
|
|
43
44
|
export declare const MAX_JSON_FILE_BYTES = 1048576;
|
|
44
45
|
/** A lock older than this is treated as abandoned and reclaimed. */
|
|
45
|
-
export declare const LOCK_STALE_MILLISECONDS =
|
|
46
|
+
export declare const LOCK_STALE_MILLISECONDS = 60000;
|
|
46
47
|
export interface StateDirectoryOptions {
|
|
47
48
|
platform?: NodeJS.Platform;
|
|
48
49
|
environment?: Readonly<Record<string, string | undefined>>;
|
|
@@ -108,7 +109,7 @@ export declare function readSnapshotCache(directory?: string): Promise<CacheRead
|
|
|
108
109
|
* so a fold can remove them properly instead of merging around a filtered view
|
|
109
110
|
* and quietly resurrecting what it could not see.
|
|
110
111
|
*/
|
|
111
|
-
export declare function readCacheState(directory?: string): Promise<{
|
|
112
|
+
export declare function readCacheState(directory?: string, fileName?: string): Promise<{
|
|
112
113
|
ok: true;
|
|
113
114
|
state: CacheState;
|
|
114
115
|
} | {
|
|
@@ -123,6 +124,13 @@ export declare function readCacheState(directory?: string): Promise<{
|
|
|
123
124
|
* after the rename cannot leave an empty file behind.
|
|
124
125
|
*/
|
|
125
126
|
export declare function writeFileAtomically(target: string, contents: string): Promise<void>;
|
|
127
|
+
/**
|
|
128
|
+
* Run one cache mutation while holding the single cache lock.
|
|
129
|
+
*
|
|
130
|
+
* Readers never take this lock. They rely on the atomic replacement below, so
|
|
131
|
+
* the lock exists only to keep two writers from interleaving.
|
|
132
|
+
*/
|
|
133
|
+
export declare function withStateLock<Result>(directory: string, action: () => Promise<Result>): Promise<Result>;
|
|
126
134
|
/**
|
|
127
135
|
* Document version of the snapshot cache.
|
|
128
136
|
*
|
|
@@ -151,6 +159,9 @@ export declare const CACHE_DOCUMENT_VERSION = 3;
|
|
|
151
159
|
* stamp so a writer that died cannot freeze the cache forever.
|
|
152
160
|
*/
|
|
153
161
|
export declare function writeSnapshotCache(snapshots: readonly Snapshot[], directory?: string): Promise<void>;
|
|
162
|
+
/** Poll owned rows live apart from the statusline cache so legacy runtimes can
|
|
163
|
+
* never overwrite a weekly usage value. */
|
|
164
|
+
export declare function mergeAuthoritativeSnapshotCache(incoming: readonly Snapshot[], directory?: string, now?: string): Promise<Snapshot[]>;
|
|
154
165
|
export interface CacheMergeResult {
|
|
155
166
|
merged: Snapshot[];
|
|
156
167
|
written: boolean;
|
package/dist/cache.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"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"}
|
package/dist/cache.js
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import { freshnessPolicy, retainSnapshots } from "./data-rules.js";
|
|
1
|
+
import { freshnessPolicy, isSnapshotDisplayEligible, retainSnapshots } from "./data-rules.js";
|
|
2
2
|
export { freshnessPolicy } from "./data-rules.js";
|
|
3
3
|
import { randomUUID } from "node:crypto";
|
|
4
4
|
import { constants } from "node:fs";
|
|
5
|
-
import { chmod, lstat, mkdir, open, readFile, rename, unlink } from "node:fs/promises";
|
|
5
|
+
import { chmod, lstat, mkdir, open, readFile, rename, rm, unlink } from "node:fs/promises";
|
|
6
6
|
import { homedir } from "node:os";
|
|
7
7
|
import path from "node:path";
|
|
8
8
|
import { applyCollectionReport, readSuppressions, snapshotBelongsTo, visibleSnapshots } from "./collection.js";
|
|
9
9
|
import { MAX_CACHE_ENTRIES, mergeSnapshots, snapshotIdentity } from "./merge.js";
|
|
10
10
|
import { canonicalJson, normalizeMeter, normalizeMeters } from "./normalizer.js";
|
|
11
11
|
export const CACHE_FILE_NAME = "openlimiter-cache.json";
|
|
12
|
+
export const AUTHORITATIVE_CACHE_FILE_NAME = "openlimiter-authoritative.json";
|
|
12
13
|
export const MAX_POLICY_TIMESTAMP = 253_402_300_799_999;
|
|
13
14
|
/** Pure policy shared with the desktop contract. All instants are UTC. */
|
|
14
15
|
export function retryPolicy(input) {
|
|
@@ -125,7 +126,7 @@ export const CACHE_LOCK_NAME = "openlimiter.lock";
|
|
|
125
126
|
/** Largest JSON document this package will read into memory. */
|
|
126
127
|
export const MAX_JSON_FILE_BYTES = 1_048_576;
|
|
127
128
|
/** A lock older than this is treated as abandoned and reclaimed. */
|
|
128
|
-
export const LOCK_STALE_MILLISECONDS =
|
|
129
|
+
export const LOCK_STALE_MILLISECONDS = 60_000;
|
|
129
130
|
/** The longest pause between lock acquisition attempts. It is not a deadline. */
|
|
130
131
|
const LOCK_BACKOFF_CEILING_MILLISECONDS = 25;
|
|
131
132
|
export function resolveStateDirectory(options = {}) {
|
|
@@ -246,8 +247,21 @@ export async function readSnapshotCache(directory = resolveStateDirectory()) {
|
|
|
246
247
|
return { ok: false, reason: "unsafe" };
|
|
247
248
|
}
|
|
248
249
|
const document = await readJsonFileSafely(path.join(directory, CACHE_FILE_NAME));
|
|
249
|
-
if (!document.ok)
|
|
250
|
-
|
|
250
|
+
if (!document.ok) {
|
|
251
|
+
if (document.reason !== "missing")
|
|
252
|
+
return document;
|
|
253
|
+
const authoritative = await readJsonFileSafely(path.join(directory, AUTHORITATIVE_CACHE_FILE_NAME));
|
|
254
|
+
if (!authoritative.ok)
|
|
255
|
+
return authoritative.reason === "missing" ? document : authoritative;
|
|
256
|
+
if (!isRecord(authoritative.value) || !Array.isArray(authoritative.value["snapshots"])) {
|
|
257
|
+
return { ok: false, reason: "corrupt" };
|
|
258
|
+
}
|
|
259
|
+
const snapshots = normalizeMeters(authoritative.value["snapshots"]);
|
|
260
|
+
return { ok: true, snapshots: snapshots.filter(isSnapshotDisplayEligible), dropped: authoritative.value["snapshots"].length - snapshots.length, suppressed: 0, suppressions: [] };
|
|
261
|
+
}
|
|
262
|
+
const authoritative = await readJsonFileSafely(path.join(directory, AUTHORITATIVE_CACHE_FILE_NAME));
|
|
263
|
+
if (!authoritative.ok && authoritative.reason !== "missing")
|
|
264
|
+
return authoritative;
|
|
251
265
|
if (!isRecord(document.value))
|
|
252
266
|
return { ok: false, reason: "corrupt" };
|
|
253
267
|
const rawSnapshots = document.value["snapshots"];
|
|
@@ -262,8 +276,16 @@ export async function readSnapshotCache(directory = resolveStateDirectory()) {
|
|
|
262
276
|
return { ok: false, reason: "corrupt" };
|
|
263
277
|
}
|
|
264
278
|
const migrated = migrateLegacyMeterIdentities(rawSnapshots, version);
|
|
265
|
-
const
|
|
266
|
-
const
|
|
279
|
+
const mainValidated = normalizeMeters(migrated);
|
|
280
|
+
const authoritativeRows = authoritative.ok && isRecord(authoritative.value) &&
|
|
281
|
+
Array.isArray(authoritative.value["snapshots"]) && authoritative.value["snapshots"].length <= MAX_CACHE_ENTRIES
|
|
282
|
+
? normalizeMeters(authoritative.value["snapshots"])
|
|
283
|
+
: [];
|
|
284
|
+
const authoritativeIdentities = new Set(authoritativeRows.map(snapshotIdentity));
|
|
285
|
+
const validated = authoritativeRows.length > 0
|
|
286
|
+
? mergeSnapshots(mainValidated.filter((snapshot) => !authoritativeIdentities.has(snapshotIdentity(snapshot))), authoritativeRows)
|
|
287
|
+
: mainValidated;
|
|
288
|
+
const dropped = rawSnapshots.length - mainValidated.length;
|
|
267
289
|
const read = readSuppressions(document.value["suppressions"]);
|
|
268
290
|
if (!read.ok) {
|
|
269
291
|
/* Unreadable suppressions make every identity in the document unknown.
|
|
@@ -291,14 +313,14 @@ export async function readSnapshotCache(directory = resolveStateDirectory()) {
|
|
|
291
313
|
* so a fold can remove them properly instead of merging around a filtered view
|
|
292
314
|
* and quietly resurrecting what it could not see.
|
|
293
315
|
*/
|
|
294
|
-
export async function readCacheState(directory = resolveStateDirectory()) {
|
|
316
|
+
export async function readCacheState(directory = resolveStateDirectory(), fileName = CACHE_FILE_NAME) {
|
|
295
317
|
try {
|
|
296
318
|
await rejectSymlink(directory);
|
|
297
319
|
}
|
|
298
320
|
catch {
|
|
299
321
|
return { ok: false, reason: "unsafe" };
|
|
300
322
|
}
|
|
301
|
-
const document = await readJsonFileSafely(path.join(directory,
|
|
323
|
+
const document = await readJsonFileSafely(path.join(directory, fileName));
|
|
302
324
|
if (!document.ok)
|
|
303
325
|
return document;
|
|
304
326
|
if (!isRecord(document.value))
|
|
@@ -386,64 +408,87 @@ export async function writeFileAtomically(target, contents) {
|
|
|
386
408
|
await unlink(tempPath).catch(() => undefined);
|
|
387
409
|
}
|
|
388
410
|
}
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
* The owner stamp inside the lock is the primary signal. An empty or unreadable
|
|
393
|
-
* lock falls back to the file modification time, which covers the short window
|
|
394
|
-
* between creating the lock and writing the stamp into it.
|
|
395
|
-
*/
|
|
396
|
-
async function reclaimStaleLock(lockPath) {
|
|
397
|
-
const now = Date.now();
|
|
398
|
-
let heldSince = null;
|
|
399
|
-
let observedContents = null;
|
|
411
|
+
async function processIsAlive(pid) {
|
|
412
|
+
if (!Number.isSafeInteger(pid) || pid <= 0)
|
|
413
|
+
return false;
|
|
400
414
|
try {
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
const stamp = isRecord(parsed) ? parsed["at"] : undefined;
|
|
404
|
-
if (typeof stamp === "number" && Number.isFinite(stamp) && stamp <= now) {
|
|
405
|
-
heldSince = stamp;
|
|
406
|
-
}
|
|
415
|
+
process.kill(pid, 0);
|
|
416
|
+
return true;
|
|
407
417
|
}
|
|
408
|
-
catch {
|
|
409
|
-
|
|
418
|
+
catch (error) {
|
|
419
|
+
return errorCode(error) === "EPERM";
|
|
410
420
|
}
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
let
|
|
421
|
+
}
|
|
422
|
+
async function reclaimStaleLock(lockPath) {
|
|
423
|
+
let stat;
|
|
414
424
|
try {
|
|
415
|
-
|
|
416
|
-
observedDevice = observed.dev;
|
|
417
|
-
observedInode = observed.ino;
|
|
418
|
-
modificationTime = observed.mtimeMs;
|
|
425
|
+
stat = await lstat(lockPath);
|
|
419
426
|
}
|
|
420
427
|
catch (error) {
|
|
421
428
|
if (errorCode(error) === "ENOENT")
|
|
422
429
|
return true;
|
|
423
430
|
throw error;
|
|
424
431
|
}
|
|
425
|
-
if (
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
432
|
+
if (!stat.isDirectory() || stat.isSymbolicLink())
|
|
433
|
+
throw new Error("Unsafe state lock");
|
|
434
|
+
const ownerPath = path.join(lockPath, "owner.json");
|
|
435
|
+
let owner = null;
|
|
436
|
+
try {
|
|
437
|
+
const parsed = JSON.parse(await readFile(ownerPath, "utf8"));
|
|
438
|
+
if (isRecord(parsed) &&
|
|
439
|
+
Number.isSafeInteger(parsed["pid"]) &&
|
|
440
|
+
typeof parsed["startedAt"] === "number" &&
|
|
441
|
+
Number.isFinite(parsed["startedAt"]) &&
|
|
442
|
+
typeof parsed["token"] === "string") {
|
|
443
|
+
owner = {
|
|
444
|
+
pid: parsed["pid"],
|
|
445
|
+
startedAt: parsed["startedAt"],
|
|
446
|
+
token: parsed["token"]
|
|
447
|
+
};
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
catch {
|
|
451
|
+
/* A process can die between mkdir and the owner write. The directory mtime
|
|
452
|
+
is the only honest signal until the owner stamp exists. */
|
|
429
453
|
}
|
|
430
|
-
|
|
454
|
+
const now = Date.now();
|
|
455
|
+
const stale = owner === null
|
|
456
|
+
? now - stat.mtimeMs >= LOCK_STALE_MILLISECONDS
|
|
457
|
+
: now - owner.startedAt >= LOCK_STALE_MILLISECONDS ||
|
|
458
|
+
!(await processIsAlive(owner.pid));
|
|
459
|
+
if (!stale)
|
|
431
460
|
return false;
|
|
461
|
+
const displaced = lockPath + ".reclaim." + randomUUID();
|
|
432
462
|
try {
|
|
433
|
-
|
|
434
|
-
(await readFile(lockPath, "utf8")) !== observedContents)
|
|
435
|
-
return false;
|
|
436
|
-
const observed = await lstat(lockPath);
|
|
437
|
-
if (observed.dev !== observedDevice || observed.ino !== observedInode)
|
|
438
|
-
return false;
|
|
439
|
-
await unlink(lockPath);
|
|
440
|
-
return true;
|
|
463
|
+
await rename(lockPath, displaced);
|
|
441
464
|
}
|
|
442
465
|
catch (error) {
|
|
443
466
|
if (errorCode(error) === "ENOENT")
|
|
444
467
|
return true;
|
|
445
|
-
|
|
468
|
+
return false;
|
|
469
|
+
}
|
|
470
|
+
let stillObserved = owner === null;
|
|
471
|
+
if (owner !== null) {
|
|
472
|
+
try {
|
|
473
|
+
const parsed = JSON.parse(await readFile(path.join(displaced, "owner.json"), "utf8"));
|
|
474
|
+
stillObserved = isRecord(parsed) && parsed["token"] === owner.token;
|
|
475
|
+
}
|
|
476
|
+
catch {
|
|
477
|
+
stillObserved = false;
|
|
478
|
+
}
|
|
446
479
|
}
|
|
480
|
+
else {
|
|
481
|
+
try {
|
|
482
|
+
await lstat(path.join(displaced, "owner.json"));
|
|
483
|
+
stillObserved = false;
|
|
484
|
+
}
|
|
485
|
+
catch (error) {
|
|
486
|
+
stillObserved = errorCode(error) === "ENOENT";
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
if (stillObserved)
|
|
490
|
+
await rm(displaced, { recursive: true, force: true });
|
|
491
|
+
return true;
|
|
447
492
|
}
|
|
448
493
|
const transientLockCodes = new Set(["EEXIST", "EPERM", "EACCES", "EBUSY"]);
|
|
449
494
|
async function lockPathExists(lockPath) {
|
|
@@ -462,19 +507,15 @@ async function acquireLock(lockPath) {
|
|
|
462
507
|
abandoned owner becomes stale, so neither case should discard this write. */
|
|
463
508
|
for (let attempt = 0;; attempt += 1) {
|
|
464
509
|
try {
|
|
465
|
-
|
|
466
|
-
const token =
|
|
467
|
-
|
|
468
|
-
id: randomUUID(),
|
|
469
|
-
pid: process.pid
|
|
470
|
-
});
|
|
510
|
+
await mkdir(lockPath, { mode: 0o700 });
|
|
511
|
+
const token = randomUUID();
|
|
512
|
+
const owner = { pid: process.pid, startedAt: Date.now(), token };
|
|
471
513
|
try {
|
|
472
|
-
await
|
|
473
|
-
return {
|
|
514
|
+
await writeFileAtomically(path.join(lockPath, "owner.json"), canonicalJson(owner));
|
|
515
|
+
return { token };
|
|
474
516
|
}
|
|
475
517
|
catch (error) {
|
|
476
|
-
await
|
|
477
|
-
await unlink(lockPath).catch(() => undefined);
|
|
518
|
+
await rm(lockPath, { recursive: true, force: true }).catch(() => undefined);
|
|
478
519
|
throw error;
|
|
479
520
|
}
|
|
480
521
|
}
|
|
@@ -492,13 +533,14 @@ async function acquireLock(lockPath) {
|
|
|
492
533
|
}
|
|
493
534
|
async function releaseLock(lockPath, token) {
|
|
494
535
|
try {
|
|
495
|
-
|
|
536
|
+
const parsed = JSON.parse(await readFile(path.join(lockPath, "owner.json"), "utf8"));
|
|
537
|
+
if (!isRecord(parsed) || parsed["token"] !== token)
|
|
496
538
|
return;
|
|
497
539
|
}
|
|
498
540
|
catch {
|
|
499
541
|
return;
|
|
500
542
|
}
|
|
501
|
-
await
|
|
543
|
+
await rm(lockPath, { recursive: true, force: true }).catch(() => undefined);
|
|
502
544
|
}
|
|
503
545
|
function rejectOutOfBounds(snapshots) {
|
|
504
546
|
if (snapshots.length > MAX_CACHE_ENTRIES)
|
|
@@ -516,7 +558,7 @@ const processLockQueues = new Map();
|
|
|
516
558
|
* Readers never take this lock. They rely on the atomic replacement below, so
|
|
517
559
|
* the lock exists only to keep two writers from interleaving.
|
|
518
560
|
*/
|
|
519
|
-
async function
|
|
561
|
+
export async function withStateLock(directory, action) {
|
|
520
562
|
const absoluteDirectory = path.resolve(directory);
|
|
521
563
|
const queueKey = process.platform === "win32"
|
|
522
564
|
? absoluteDirectory.toLowerCase()
|
|
@@ -533,12 +575,11 @@ async function withCacheLock(directory, action) {
|
|
|
533
575
|
await prepareStateDirectory(absoluteDirectory);
|
|
534
576
|
const lockPath = path.join(absoluteDirectory, CACHE_LOCK_NAME);
|
|
535
577
|
await rejectSymlink(lockPath);
|
|
536
|
-
const {
|
|
578
|
+
const { token } = await acquireLock(lockPath);
|
|
537
579
|
try {
|
|
538
580
|
return await action();
|
|
539
581
|
}
|
|
540
582
|
finally {
|
|
541
|
-
await handle.close().catch(() => undefined);
|
|
542
583
|
await releaseLock(lockPath, token);
|
|
543
584
|
}
|
|
544
585
|
}
|
|
@@ -549,6 +590,8 @@ async function withCacheLock(directory, action) {
|
|
|
549
590
|
}
|
|
550
591
|
}
|
|
551
592
|
}
|
|
593
|
+
/* Snapshot and configuration writers share one state directory lock. */
|
|
594
|
+
const withCacheLock = withStateLock;
|
|
552
595
|
/**
|
|
553
596
|
* Document version of the snapshot cache.
|
|
554
597
|
*
|
|
@@ -603,6 +646,34 @@ export async function writeSnapshotCache(snapshots, directory = resolveStateDire
|
|
|
603
646
|
await replaceCache(directory, snapshots);
|
|
604
647
|
});
|
|
605
648
|
}
|
|
649
|
+
/** Poll owned rows live apart from the statusline cache so legacy runtimes can
|
|
650
|
+
* never overwrite a weekly usage value. */
|
|
651
|
+
export async function mergeAuthoritativeSnapshotCache(incoming, directory = resolveStateDirectory(), now) {
|
|
652
|
+
rejectOutOfBounds(incoming);
|
|
653
|
+
return withStateLock(directory, async () => {
|
|
654
|
+
const cached = await readCacheState(directory, AUTHORITATIVE_CACHE_FILE_NAME);
|
|
655
|
+
const existing = cached.ok ? cached.state.snapshots : [];
|
|
656
|
+
const byIdentity = new Map(existing.map((row) => [snapshotIdentity(row), row]));
|
|
657
|
+
for (const row of incoming) {
|
|
658
|
+
const previous = byIdentity.get(snapshotIdentity(row));
|
|
659
|
+
if (previous === undefined || Date.parse(row.observedAt) >= Date.parse(previous.observedAt)) {
|
|
660
|
+
byIdentity.set(snapshotIdentity(row), row);
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
const retentionNow = now === undefined
|
|
664
|
+
? incoming
|
|
665
|
+
.map((row) => Date.parse(row.observedAt))
|
|
666
|
+
.filter(Number.isFinite)
|
|
667
|
+
.reduce((latest, observed) => Math.max(latest, observed), 0)
|
|
668
|
+
: Date.parse(now);
|
|
669
|
+
const rows = retainSnapshots([...byIdentity.values()], retentionNow);
|
|
670
|
+
rejectOutOfBounds(rows);
|
|
671
|
+
const target = path.join(directory, AUTHORITATIVE_CACHE_FILE_NAME);
|
|
672
|
+
await rejectSymlink(target);
|
|
673
|
+
await writeFileAtomically(target, canonicalJson({ snapshots: rows, version: CACHE_DOCUMENT_VERSION }));
|
|
674
|
+
return rows;
|
|
675
|
+
});
|
|
676
|
+
}
|
|
606
677
|
/**
|
|
607
678
|
* Fold fresh snapshots into the cache under the lock.
|
|
608
679
|
*
|