@yadsh/dsh-kv-persist 0.1.0
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/LICENSE +21 -0
- package/README.md +110 -0
- package/compatibility.json +16 -0
- package/cordis.patch.yml +4 -0
- package/docs/dsh-kv-persist.md +3311 -0
- package/lib/backends/llama-cpp/backend.d.ts +20 -0
- package/lib/backends/llama-cpp/backend.d.ts.map +1 -0
- package/lib/backends/llama-cpp/backend.js +37 -0
- package/lib/backends/llama-cpp/backend.js.map +1 -0
- package/lib/backends/llama-cpp/client.d.ts +31 -0
- package/lib/backends/llama-cpp/client.d.ts.map +1 -0
- package/lib/backends/llama-cpp/client.js +120 -0
- package/lib/backends/llama-cpp/client.js.map +1 -0
- package/lib/backends/llama-cpp/discovery.d.ts +20 -0
- package/lib/backends/llama-cpp/discovery.d.ts.map +1 -0
- package/lib/backends/llama-cpp/discovery.js +33 -0
- package/lib/backends/llama-cpp/discovery.js.map +1 -0
- package/lib/backends/llama-cpp/types.d.ts +30 -0
- package/lib/backends/llama-cpp/types.d.ts.map +1 -0
- package/lib/backends/llama-cpp/types.js +9 -0
- package/lib/backends/llama-cpp/types.js.map +1 -0
- package/lib/backends/types.d.ts +52 -0
- package/lib/backends/types.d.ts.map +1 -0
- package/lib/backends/types.js +6 -0
- package/lib/backends/types.js.map +1 -0
- package/lib/config.d.ts +258 -0
- package/lib/config.d.ts.map +1 -0
- package/lib/config.js +169 -0
- package/lib/config.js.map +1 -0
- package/lib/coordinator/checkpoint-policy.d.ts +19 -0
- package/lib/coordinator/checkpoint-policy.d.ts.map +1 -0
- package/lib/coordinator/checkpoint-policy.js +40 -0
- package/lib/coordinator/checkpoint-policy.js.map +1 -0
- package/lib/coordinator/circuit-breaker.d.ts +29 -0
- package/lib/coordinator/circuit-breaker.d.ts.map +1 -0
- package/lib/coordinator/circuit-breaker.js +62 -0
- package/lib/coordinator/circuit-breaker.js.map +1 -0
- package/lib/coordinator/coordinator.d.ts +74 -0
- package/lib/coordinator/coordinator.d.ts.map +1 -0
- package/lib/coordinator/coordinator.js +542 -0
- package/lib/coordinator/coordinator.js.map +1 -0
- package/lib/coordinator/slot-lease.d.ts +22 -0
- package/lib/coordinator/slot-lease.d.ts.map +1 -0
- package/lib/coordinator/slot-lease.js +38 -0
- package/lib/coordinator/slot-lease.js.map +1 -0
- package/lib/coordinator/state-machine.d.ts +65 -0
- package/lib/coordinator/state-machine.d.ts.map +1 -0
- package/lib/coordinator/state-machine.js +40 -0
- package/lib/coordinator/state-machine.js.map +1 -0
- package/lib/errors.d.ts +82 -0
- package/lib/errors.d.ts.map +1 -0
- package/lib/errors.js +113 -0
- package/lib/errors.js.map +1 -0
- package/lib/index.d.ts +26 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +17 -0
- package/lib/index.js.map +1 -0
- package/lib/logging/dsh-home.d.ts +13 -0
- package/lib/logging/dsh-home.d.ts.map +1 -0
- package/lib/logging/dsh-home.js +18 -0
- package/lib/logging/dsh-home.js.map +1 -0
- package/lib/logging/index.d.ts +10 -0
- package/lib/logging/index.d.ts.map +1 -0
- package/lib/logging/index.js +10 -0
- package/lib/logging/index.js.map +1 -0
- package/lib/logging/plugin-logger.d.ts +94 -0
- package/lib/logging/plugin-logger.d.ts.map +1 -0
- package/lib/logging/plugin-logger.js +397 -0
- package/lib/logging/plugin-logger.js.map +1 -0
- package/lib/observability/diagnostics.d.ts +37 -0
- package/lib/observability/diagnostics.d.ts.map +1 -0
- package/lib/observability/diagnostics.js +75 -0
- package/lib/observability/diagnostics.js.map +1 -0
- package/lib/observability/metrics.d.ts +38 -0
- package/lib/observability/metrics.d.ts.map +1 -0
- package/lib/observability/metrics.js +29 -0
- package/lib/observability/metrics.js.map +1 -0
- package/lib/service.d.ts +231 -0
- package/lib/service.d.ts.map +1 -0
- package/lib/service.js +232 -0
- package/lib/service.js.map +1 -0
- package/lib/snapshots/fingerprint.d.ts +53 -0
- package/lib/snapshots/fingerprint.d.ts.map +1 -0
- package/lib/snapshots/fingerprint.js +69 -0
- package/lib/snapshots/fingerprint.js.map +1 -0
- package/lib/snapshots/manifest.d.ts +51 -0
- package/lib/snapshots/manifest.d.ts.map +1 -0
- package/lib/snapshots/manifest.js +0 -0
- package/lib/snapshots/manifest.js.map +1 -0
- package/lib/snapshots/naming.d.ts +18 -0
- package/lib/snapshots/naming.d.ts.map +1 -0
- package/lib/snapshots/naming.js +33 -0
- package/lib/snapshots/naming.js.map +1 -0
- package/lib/snapshots/repository.d.ts +52 -0
- package/lib/snapshots/repository.d.ts.map +1 -0
- package/lib/snapshots/repository.js +270 -0
- package/lib/snapshots/repository.js.map +1 -0
- package/package.json +83 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single-slot coordinator (SPEC §7, §20-§29, §50-§53, §69-§72).
|
|
3
|
+
*
|
|
4
|
+
* Owns the mapping `DSH session -> llama.cpp slot -> persistent snapshot`
|
|
5
|
+
* for exactly one physical slot. All slot mutations run inside one slot
|
|
6
|
+
* mutex (Invariant 8); the session log of DSH remains the only source of
|
|
7
|
+
* truth and every persistence failure degrades to cold inference
|
|
8
|
+
* (Invariants 1, 5).
|
|
9
|
+
*/
|
|
10
|
+
import type { StreamChunk } from "@deepseek-ai/dsh-llm";
|
|
11
|
+
import type { KvPersistenceBackend } from "../backends/types.js";
|
|
12
|
+
import type { ResolvedKvPersistConfig } from "../config.js";
|
|
13
|
+
import type { SnapshotRepository } from "../snapshots/repository.js";
|
|
14
|
+
import type { KvPersistLogger } from "../observability/diagnostics.js";
|
|
15
|
+
import type { KvPersistMetrics } from "../observability/metrics.js";
|
|
16
|
+
import type { SnapshotInvalidationReason } from "../errors.js";
|
|
17
|
+
import type { CheckpointTrigger } from "./checkpoint-policy.js";
|
|
18
|
+
import type { ManagedSlot, RestoreOutcome, SessionRuntime, SnapshotResult } from "./state-machine.js";
|
|
19
|
+
/** One coordinated llm/stream request. */
|
|
20
|
+
export interface CoordinatorRequest {
|
|
21
|
+
/** DSH session identity; null for requests outside any session. */
|
|
22
|
+
readonly sessionId: string | null;
|
|
23
|
+
readonly provider: string;
|
|
24
|
+
readonly model: string;
|
|
25
|
+
/** Auxiliary classification (compaction, session-title); set for aux calls. */
|
|
26
|
+
readonly purpose?: string;
|
|
27
|
+
/** Waterfall continuation producing the downstream stream; called once. */
|
|
28
|
+
readonly next: () => AsyncIterable<StreamChunk>;
|
|
29
|
+
}
|
|
30
|
+
export interface CoordinatorOptions {
|
|
31
|
+
readonly config: ResolvedKvPersistConfig;
|
|
32
|
+
readonly backend: KvPersistenceBackend;
|
|
33
|
+
readonly repository: SnapshotRepository;
|
|
34
|
+
readonly metrics: KvPersistMetrics;
|
|
35
|
+
readonly logger: KvPersistLogger;
|
|
36
|
+
readonly now?: () => number;
|
|
37
|
+
}
|
|
38
|
+
export declare class SingleSlotCoordinator {
|
|
39
|
+
#private;
|
|
40
|
+
constructor(options: CoordinatorOptions);
|
|
41
|
+
get slot(): Readonly<ManagedSlot>;
|
|
42
|
+
get circuitState(): string;
|
|
43
|
+
getSessionState(sessionId: string): SessionRuntime | undefined;
|
|
44
|
+
/**
|
|
45
|
+
* Handle one llm/stream request for a managed provider. The returned
|
|
46
|
+
* iterable wraps the downstream stream transparently: every chunk is
|
|
47
|
+
* yielded unchanged, streaming is preserved (SPEC §25), and a successful
|
|
48
|
+
* terminal finish marks the session dirty.
|
|
49
|
+
*/
|
|
50
|
+
runSessionRequest(input: CoordinatorRequest): Promise<AsyncIterable<StreamChunk>>;
|
|
51
|
+
/** Public checkpoint entry for triggers coming from session events. */
|
|
52
|
+
checkpoint(sessionId: string, trigger: CheckpointTrigger): Promise<SnapshotResult | null>;
|
|
53
|
+
/** Session disposal (SPEC §50): checkpoint if configured, release, forget. */
|
|
54
|
+
handleSessionDisposed(sessionId: string): Promise<void>;
|
|
55
|
+
/** Save every dirty session that still owns the slot (flush/shutdown). */
|
|
56
|
+
flushOwned(trigger: CheckpointTrigger): Promise<void>;
|
|
57
|
+
/** Explicit restore for the service API (SPEC §11 `restore`). */
|
|
58
|
+
restoreNow(sessionId: string): Promise<RestoreOutcome>;
|
|
59
|
+
/** Explicit save for the service API (SPEC §11 `save`). */
|
|
60
|
+
saveNow(sessionId: string): Promise<SnapshotResult>;
|
|
61
|
+
/** Invalidate every snapshot of a session without deleting data (§31). */
|
|
62
|
+
invalidate(sessionId: string, reason?: SnapshotInvalidationReason): Promise<void>;
|
|
63
|
+
/** Purge all metadata of a session (SPEC §11 `purge`). */
|
|
64
|
+
purge(sessionId: string): Promise<void>;
|
|
65
|
+
/** Probe the backend (SPEC §34); resets the breaker on success. */
|
|
66
|
+
probeBackend(): Promise<{
|
|
67
|
+
healthy: boolean;
|
|
68
|
+
slotIds: readonly number[];
|
|
69
|
+
error: string | null;
|
|
70
|
+
}>;
|
|
71
|
+
/** Shutdown (SPEC §58): stop work, cancel timers, final checkpoint. */
|
|
72
|
+
dispose(): Promise<void>;
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=coordinator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coordinator.d.ts","sourceRoot":"","sources":["../../src/coordinator/coordinator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,542 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single-slot coordinator (SPEC §7, §20-§29, §50-§53, §69-§72).
|
|
3
|
+
*
|
|
4
|
+
* Owns the mapping `DSH session -> llama.cpp slot -> persistent snapshot`
|
|
5
|
+
* for exactly one physical slot. All slot mutations run inside one slot
|
|
6
|
+
* mutex (Invariant 8); the session log of DSH remains the only source of
|
|
7
|
+
* truth and every persistence failure degrades to cold inference
|
|
8
|
+
* (Invariants 1, 5).
|
|
9
|
+
*/
|
|
10
|
+
import { buildSnapshotIdentity } from "../snapshots/fingerprint.js";
|
|
11
|
+
import { assertPluginGeneratedFilename, snapshotFilename } from "../snapshots/naming.js";
|
|
12
|
+
import { abbreviateSessionId } from "../observability/diagnostics.js";
|
|
13
|
+
import { KvPersistError, KvRestoreFailedError } from "../errors.js";
|
|
14
|
+
import { CheckpointPolicy } from "./checkpoint-policy.js";
|
|
15
|
+
import { CircuitBreaker } from "./circuit-breaker.js";
|
|
16
|
+
import { SlotMutex } from "./slot-lease.js";
|
|
17
|
+
import { createManagedSlot, createSessionRuntime, isDirty, markDirty, markPersisted, } from "./state-machine.js";
|
|
18
|
+
export class SingleSlotCoordinator {
|
|
19
|
+
#config;
|
|
20
|
+
#backend;
|
|
21
|
+
#repository;
|
|
22
|
+
#metrics;
|
|
23
|
+
#logger;
|
|
24
|
+
#mutex;
|
|
25
|
+
#policy;
|
|
26
|
+
#breaker;
|
|
27
|
+
#slot;
|
|
28
|
+
#sessions = new Map();
|
|
29
|
+
#now;
|
|
30
|
+
#idleTimer = null;
|
|
31
|
+
#idleTimerSession = null;
|
|
32
|
+
#disposed = false;
|
|
33
|
+
constructor(options) {
|
|
34
|
+
this.#config = options.config;
|
|
35
|
+
this.#backend = options.backend;
|
|
36
|
+
this.#repository = options.repository;
|
|
37
|
+
this.#metrics = options.metrics;
|
|
38
|
+
this.#logger = options.logger;
|
|
39
|
+
this.#now = options.now ?? Date.now;
|
|
40
|
+
this.#mutex = new SlotMutex(`llama-slot-${options.config.slotId}`);
|
|
41
|
+
this.#policy = new CheckpointPolicy(options.config);
|
|
42
|
+
this.#breaker = new CircuitBreaker({
|
|
43
|
+
maxConsecutiveFailures: options.config.failure.maxConsecutiveFailures,
|
|
44
|
+
cooldownMs: options.config.failure.cooldownMs,
|
|
45
|
+
});
|
|
46
|
+
this.#slot = createManagedSlot(options.config.slotId);
|
|
47
|
+
}
|
|
48
|
+
// ——— introspection (status API, SPEC §47) ———————————————————————————
|
|
49
|
+
get slot() {
|
|
50
|
+
return this.#slot;
|
|
51
|
+
}
|
|
52
|
+
get circuitState() {
|
|
53
|
+
return this.#breaker.state;
|
|
54
|
+
}
|
|
55
|
+
getSessionState(sessionId) {
|
|
56
|
+
return this.#sessions.get(sessionId);
|
|
57
|
+
}
|
|
58
|
+
// ——— request coordination (SPEC §21, §22, §69-§72) ——————————————————
|
|
59
|
+
/**
|
|
60
|
+
* Handle one llm/stream request for a managed provider. The returned
|
|
61
|
+
* iterable wraps the downstream stream transparently: every chunk is
|
|
62
|
+
* yielded unchanged, streaming is preserved (SPEC §25), and a successful
|
|
63
|
+
* terminal finish marks the session dirty.
|
|
64
|
+
*/
|
|
65
|
+
async runSessionRequest(input) {
|
|
66
|
+
if (input.purpose !== undefined || input.sessionId === null) {
|
|
67
|
+
this.#metrics.counters.auxiliaryRequests += 1;
|
|
68
|
+
return this.#runAuxiliary(input);
|
|
69
|
+
}
|
|
70
|
+
const sessionId = input.sessionId;
|
|
71
|
+
this.#ensureRuntime(sessionId, input);
|
|
72
|
+
return this.#mutex.runExclusive(async () => {
|
|
73
|
+
this.#cancelIdleTimer();
|
|
74
|
+
if (this.#breaker.isOpen(this.#now())) {
|
|
75
|
+
this.#metrics.counters.circuitSkips += 1;
|
|
76
|
+
this.#logger.debug("kv.persistence.circuit_open", { sessionId });
|
|
77
|
+
this.#loseSlotTracking();
|
|
78
|
+
return this.#execute(input);
|
|
79
|
+
}
|
|
80
|
+
const identity = this.#identityFor(sessionId, input);
|
|
81
|
+
const outcome = await this.#prepareSession(sessionId, identity);
|
|
82
|
+
if (this.#config.failure.strict && outcome.kind === "cold-fallback") {
|
|
83
|
+
// SPEC §32: only strict mode turns a restore failure into a failure.
|
|
84
|
+
throw new KvRestoreFailedError(`strict mode: snapshot restore failed for session ${abbreviateSessionId(sessionId)}: ${outcome.error ?? "unknown error"}`);
|
|
85
|
+
}
|
|
86
|
+
if (this.#slot.ownerSessionId === sessionId) {
|
|
87
|
+
this.#slot.state = "inference";
|
|
88
|
+
this.#slot.lastUsedAt = this.#now();
|
|
89
|
+
}
|
|
90
|
+
return this.#execute(input);
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Auxiliary requests (session-title, compaction) participate explicitly
|
|
95
|
+
* (SPEC §22, §72): the current dirty owner is checkpointed, ownership is
|
|
96
|
+
* cleared, and the auxiliary result never becomes session state
|
|
97
|
+
* (Invariant 7).
|
|
98
|
+
*/
|
|
99
|
+
async #runAuxiliary(input) {
|
|
100
|
+
return this.#mutex.runExclusive(async () => {
|
|
101
|
+
this.#cancelIdleTimer();
|
|
102
|
+
if (this.#breaker.isOpen(this.#now())) {
|
|
103
|
+
this.#metrics.counters.circuitSkips += 1;
|
|
104
|
+
this.#loseSlotTracking();
|
|
105
|
+
return this.#execute(input);
|
|
106
|
+
}
|
|
107
|
+
const owner = this.#slot.ownerSessionId;
|
|
108
|
+
if (owner !== null) {
|
|
109
|
+
if (this.#policy.shouldCheckpoint(this.#sessions.get(owner), "switch")) {
|
|
110
|
+
await this.#saveOwnedSession(owner, "switch");
|
|
111
|
+
}
|
|
112
|
+
this.#slot.ownerSessionId = null;
|
|
113
|
+
this.#slot.state = "idle";
|
|
114
|
+
this.#logger.debug("kv.session.switch", { sessionId: owner, to: "auxiliary" });
|
|
115
|
+
}
|
|
116
|
+
return this.#execute(input);
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* The core prepare algorithm (SPEC §23): already-active fast path with
|
|
121
|
+
* zero disk I/O (Invariant 6), save-before-evict (Invariant 3), lazy
|
|
122
|
+
* restore of a compatible snapshot, or a safe cold assignment.
|
|
123
|
+
*/
|
|
124
|
+
async #prepareSession(sessionId, identity) {
|
|
125
|
+
const runtime = this.#requireRuntime(sessionId);
|
|
126
|
+
// 1. Resident fast path: no save, no restore, no management calls.
|
|
127
|
+
if (this.#slot.ownerSessionId === sessionId &&
|
|
128
|
+
this.#slot.state !== "broken" &&
|
|
129
|
+
this.#slot.state !== "unknown") {
|
|
130
|
+
runtime.lifecycle = isDirty(runtime) ? "active-dirty" : "active-clean";
|
|
131
|
+
return { kind: "already-active", sessionId, tokens: null, bytes: null, durationMs: null, error: null };
|
|
132
|
+
}
|
|
133
|
+
// 2. Save-before-evict (SPEC §52, Invariant 3).
|
|
134
|
+
const owner = this.#slot.ownerSessionId;
|
|
135
|
+
if (owner !== null && owner !== sessionId) {
|
|
136
|
+
this.#metrics.counters.slotSwitches += 1;
|
|
137
|
+
if (this.#policy.shouldCheckpoint(this.#sessions.get(owner), "switch")) {
|
|
138
|
+
await this.#saveOwnedSession(owner, "switch");
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
// 3. No compatible snapshot (or restore disabled) -> cold assignment (§53).
|
|
142
|
+
const manifest = this.#config.restore.enabled
|
|
143
|
+
? await this.#findCompatibleManifest(identity)
|
|
144
|
+
: null;
|
|
145
|
+
if (!manifest) {
|
|
146
|
+
await this.#eraseSlotBestEffort();
|
|
147
|
+
this.#assignSlot(sessionId, "idle");
|
|
148
|
+
runtime.lifecycle = "cold";
|
|
149
|
+
this.#metrics.counters.coldPrefills += 1;
|
|
150
|
+
this.#logger.info("kv.session.cold", { sessionId, slot: this.#slot.id });
|
|
151
|
+
return { kind: "cold", sessionId, tokens: null, bytes: null, durationMs: null, error: null };
|
|
152
|
+
}
|
|
153
|
+
// 4. Lazy restore (SPEC §23-§24).
|
|
154
|
+
const startedAt = this.#now();
|
|
155
|
+
this.#slot.state = "restoring";
|
|
156
|
+
runtime.lifecycle = "restoring";
|
|
157
|
+
this.#logger.debug("kv.session.restore.start", { sessionId, slot: this.#slot.id });
|
|
158
|
+
try {
|
|
159
|
+
assertPluginGeneratedFilename(manifest.snapshotFilename);
|
|
160
|
+
const result = await this.#backend.restoreSlot(this.#slot.id, manifest.snapshotFilename);
|
|
161
|
+
if (this.#config.restore.verify && result.nRestored !== null && result.nRestored <= 0) {
|
|
162
|
+
throw new KvRestoreFailedError(`restore verification failed: server reported n_restored=${String(result.nRestored)} (SPEC §24)`);
|
|
163
|
+
}
|
|
164
|
+
const durationMs = this.#now() - startedAt;
|
|
165
|
+
this.#assignSlot(sessionId, "ready");
|
|
166
|
+
runtime.lifecycle = "active-clean";
|
|
167
|
+
this.#metrics.counters.restores += 1;
|
|
168
|
+
this.#metrics.counters.restoreHits += 1;
|
|
169
|
+
this.#metrics.counters.restoreDurationMs += durationMs;
|
|
170
|
+
this.#breaker.recordSuccess();
|
|
171
|
+
this.#logger.info("kv.session.restore.success", {
|
|
172
|
+
sessionId,
|
|
173
|
+
slot: this.#slot.id,
|
|
174
|
+
tokens: result.nRestored,
|
|
175
|
+
durationMs,
|
|
176
|
+
});
|
|
177
|
+
return {
|
|
178
|
+
kind: "restored",
|
|
179
|
+
sessionId,
|
|
180
|
+
tokens: result.nRestored,
|
|
181
|
+
bytes: manifest.bytes,
|
|
182
|
+
durationMs,
|
|
183
|
+
error: null,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
catch (error) {
|
|
187
|
+
// Restore failure is never fatal unless strict mode (SPEC §23, §32).
|
|
188
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
189
|
+
await this.#repository
|
|
190
|
+
.markInvalid(identity, "RESTORE_FAILED", this.#iso())
|
|
191
|
+
.catch(() => undefined);
|
|
192
|
+
await this.#eraseSlotBestEffort();
|
|
193
|
+
this.#assignSlot(sessionId, "idle");
|
|
194
|
+
runtime.lifecycle = "cold";
|
|
195
|
+
this.#metrics.counters.restoreFailures += 1;
|
|
196
|
+
this.#metrics.counters.coldPrefills += 1;
|
|
197
|
+
this.#breaker.recordFailure(this.#now());
|
|
198
|
+
this.#logger.warn("kv.session.restore.failed", {
|
|
199
|
+
sessionId,
|
|
200
|
+
code: error instanceof KvPersistError ? error.code : "KV_RESTORE_FAILED",
|
|
201
|
+
error: message,
|
|
202
|
+
});
|
|
203
|
+
return { kind: "cold-fallback", sessionId, tokens: null, bytes: null, durationMs: null, error: message };
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Wrap the downstream stream (SPEC §25): chunks pass through unchanged
|
|
208
|
+
* and unbuffered; only the terminal state is observed. `next()` was
|
|
209
|
+
* already invoked exactly once inside the lock before wrapping.
|
|
210
|
+
*/
|
|
211
|
+
#execute(input) {
|
|
212
|
+
const downstream = input.next();
|
|
213
|
+
const sessionId = input.purpose === undefined ? input.sessionId : null;
|
|
214
|
+
const finish = (succeeded) => {
|
|
215
|
+
if (succeeded && sessionId !== null)
|
|
216
|
+
this.#onInferenceSuccess(sessionId);
|
|
217
|
+
};
|
|
218
|
+
async function* wrapped() {
|
|
219
|
+
let succeeded = false;
|
|
220
|
+
try {
|
|
221
|
+
for await (const chunk of downstream) {
|
|
222
|
+
if (chunk.type === "finish" &&
|
|
223
|
+
chunk.reason.kind !== "error" &&
|
|
224
|
+
chunk.reason.kind !== "aborted") {
|
|
225
|
+
succeeded = true;
|
|
226
|
+
}
|
|
227
|
+
yield chunk;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
finally {
|
|
231
|
+
finish(succeeded);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
return wrapped();
|
|
235
|
+
}
|
|
236
|
+
/** Post-inference bookkeeping: dirty generation + idle checkpoint timer. */
|
|
237
|
+
#onInferenceSuccess(sessionId) {
|
|
238
|
+
const runtime = this.#sessions.get(sessionId);
|
|
239
|
+
if (runtime !== undefined)
|
|
240
|
+
markDirty(runtime);
|
|
241
|
+
// Recheck ownership: a switch may have happened while the stream was open.
|
|
242
|
+
if (this.#slot.ownerSessionId === sessionId) {
|
|
243
|
+
this.#slot.state = "dirty";
|
|
244
|
+
this.#slot.lastUsedAt = this.#now();
|
|
245
|
+
this.#scheduleIdleCheckpoint(sessionId);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
// ——— checkpointing (SPEC §26-§28, §71) ———————————————————————————————
|
|
249
|
+
/**
|
|
250
|
+
* Save the session that owns the slot, with generation coalescing:
|
|
251
|
+
* a clean session is skipped and an in-flight save for the same
|
|
252
|
+
* generation is awaited rather than duplicated (SPEC §27).
|
|
253
|
+
*/
|
|
254
|
+
async #saveOwnedSession(sessionId, trigger) {
|
|
255
|
+
const runtime = this.#sessions.get(sessionId);
|
|
256
|
+
if (runtime === undefined || !isDirty(runtime)) {
|
|
257
|
+
return { kind: "skipped-clean", sessionId, revision: runtime?.persistedRevision ?? 0, bytes: null, error: null };
|
|
258
|
+
}
|
|
259
|
+
if (this.#slot.ownerSessionId !== sessionId) {
|
|
260
|
+
return { kind: "skipped-not-owner", sessionId, revision: runtime.dirtyRevision, bytes: null, error: null };
|
|
261
|
+
}
|
|
262
|
+
if (runtime.saveInFlight !== null)
|
|
263
|
+
return runtime.saveInFlight;
|
|
264
|
+
const identity = this.#identityFor(sessionId, runtime.route);
|
|
265
|
+
const generation = runtime.dirtyRevision;
|
|
266
|
+
const startedAt = this.#now();
|
|
267
|
+
this.#slot.state = "saving";
|
|
268
|
+
runtime.lifecycle = "saving";
|
|
269
|
+
this.#logger.debug("kv.session.save.start", { sessionId, trigger });
|
|
270
|
+
const attempt = (async () => {
|
|
271
|
+
try {
|
|
272
|
+
assertPluginGeneratedFilename(snapshotFilename(identity));
|
|
273
|
+
const saved = await this.#backend.saveSlot(this.#slot.id, snapshotFilename(identity));
|
|
274
|
+
await this.#repository.put({
|
|
275
|
+
identity,
|
|
276
|
+
slotId: this.#slot.id,
|
|
277
|
+
sessionSeq: null,
|
|
278
|
+
tokens: null,
|
|
279
|
+
bytes: saved.bytes,
|
|
280
|
+
now: this.#iso(),
|
|
281
|
+
});
|
|
282
|
+
markPersisted(runtime, generation);
|
|
283
|
+
if (this.#slot.ownerSessionId === sessionId)
|
|
284
|
+
this.#slot.state = "ready";
|
|
285
|
+
this.#breaker.recordSuccess();
|
|
286
|
+
const durationMs = this.#now() - startedAt;
|
|
287
|
+
this.#metrics.counters.saves += 1;
|
|
288
|
+
this.#metrics.counters.saveDurationMs += durationMs;
|
|
289
|
+
this.#logger.info("kv.session.save.success", {
|
|
290
|
+
sessionId,
|
|
291
|
+
trigger,
|
|
292
|
+
revision: generation,
|
|
293
|
+
durationMs,
|
|
294
|
+
});
|
|
295
|
+
return { kind: "saved", sessionId, revision: generation, bytes: saved.bytes, error: null };
|
|
296
|
+
}
|
|
297
|
+
catch (error) {
|
|
298
|
+
// Save failure never fails the session (SPEC §32): stay dirty, log.
|
|
299
|
+
this.#breaker.recordFailure(this.#now());
|
|
300
|
+
this.#metrics.counters.saveFailures += 1;
|
|
301
|
+
if (this.#slot.ownerSessionId === sessionId)
|
|
302
|
+
this.#slot.state = "dirty";
|
|
303
|
+
runtime.lifecycle = "active-dirty";
|
|
304
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
305
|
+
this.#logger.warn("kv.session.save.failed", {
|
|
306
|
+
sessionId,
|
|
307
|
+
trigger,
|
|
308
|
+
code: error instanceof KvPersistError ? error.code : "KV_SAVE_FAILED",
|
|
309
|
+
error: message,
|
|
310
|
+
});
|
|
311
|
+
return { kind: "failed", sessionId, revision: generation, bytes: null, error: message };
|
|
312
|
+
}
|
|
313
|
+
finally {
|
|
314
|
+
runtime.saveInFlight = null;
|
|
315
|
+
}
|
|
316
|
+
})();
|
|
317
|
+
runtime.saveInFlight = attempt;
|
|
318
|
+
return attempt;
|
|
319
|
+
}
|
|
320
|
+
/** Public checkpoint entry for triggers coming from session events. */
|
|
321
|
+
async checkpoint(sessionId, trigger) {
|
|
322
|
+
if (this.#disposed)
|
|
323
|
+
return null;
|
|
324
|
+
return this.#mutex.runExclusive(async () => {
|
|
325
|
+
if (!this.#policy.shouldCheckpoint(this.#sessions.get(sessionId), trigger))
|
|
326
|
+
return null;
|
|
327
|
+
if (this.#breaker.isOpen(this.#now()))
|
|
328
|
+
return null;
|
|
329
|
+
return this.#saveOwnedSession(sessionId, trigger);
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
/** Session disposal (SPEC §50): checkpoint if configured, release, forget. */
|
|
333
|
+
async handleSessionDisposed(sessionId) {
|
|
334
|
+
if (this.#disposed)
|
|
335
|
+
return;
|
|
336
|
+
await this.#mutex.runExclusive(async () => {
|
|
337
|
+
const runtime = this.#sessions.get(sessionId);
|
|
338
|
+
if (runtime !== undefined &&
|
|
339
|
+
this.#slot.ownerSessionId === sessionId &&
|
|
340
|
+
this.#policy.shouldCheckpoint(runtime, "session-disposed") &&
|
|
341
|
+
!this.#breaker.isOpen(this.#now())) {
|
|
342
|
+
await this.#saveOwnedSession(sessionId, "session-disposed");
|
|
343
|
+
}
|
|
344
|
+
if (this.#slot.ownerSessionId === sessionId) {
|
|
345
|
+
this.#slot.ownerSessionId = null;
|
|
346
|
+
this.#slot.state = "idle";
|
|
347
|
+
}
|
|
348
|
+
this.#sessions.delete(sessionId);
|
|
349
|
+
if (this.#idleTimerSession === sessionId)
|
|
350
|
+
this.#cancelIdleTimer();
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
/** Save every dirty session that still owns the slot (flush/shutdown). */
|
|
354
|
+
async flushOwned(trigger) {
|
|
355
|
+
if (this.#disposed)
|
|
356
|
+
return;
|
|
357
|
+
await this.#mutex.runExclusive(async () => {
|
|
358
|
+
const owner = this.#slot.ownerSessionId;
|
|
359
|
+
if (owner === null)
|
|
360
|
+
return;
|
|
361
|
+
if (!this.#policy.shouldCheckpoint(this.#sessions.get(owner), trigger))
|
|
362
|
+
return;
|
|
363
|
+
if (this.#breaker.isOpen(this.#now()))
|
|
364
|
+
return;
|
|
365
|
+
await this.#saveOwnedSession(owner, trigger);
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
/** Idle checkpoint (SPEC §71): recheck ownership before saving. */
|
|
369
|
+
#scheduleIdleCheckpoint(sessionId) {
|
|
370
|
+
this.#cancelIdleTimer();
|
|
371
|
+
if (this.#config.checkpoint.idleMs <= 0)
|
|
372
|
+
return;
|
|
373
|
+
this.#idleTimerSession = sessionId;
|
|
374
|
+
this.#idleTimer = setTimeout(() => {
|
|
375
|
+
this.#idleTimer = null;
|
|
376
|
+
this.#idleTimerSession = null;
|
|
377
|
+
void this.#mutex.runExclusive(async () => {
|
|
378
|
+
if (this.#disposed)
|
|
379
|
+
return;
|
|
380
|
+
if (this.#slot.ownerSessionId !== sessionId)
|
|
381
|
+
return;
|
|
382
|
+
const runtime = this.#sessions.get(sessionId);
|
|
383
|
+
if (!this.#policy.shouldCheckpoint(runtime, "idle"))
|
|
384
|
+
return;
|
|
385
|
+
if (this.#breaker.isOpen(this.#now()))
|
|
386
|
+
return;
|
|
387
|
+
await this.#saveOwnedSession(sessionId, "idle");
|
|
388
|
+
});
|
|
389
|
+
}, this.#config.checkpoint.idleMs);
|
|
390
|
+
// The timer must never keep the host process alive.
|
|
391
|
+
this.#idleTimer.unref?.();
|
|
392
|
+
}
|
|
393
|
+
#cancelIdleTimer() {
|
|
394
|
+
if (this.#idleTimer !== null) {
|
|
395
|
+
clearTimeout(this.#idleTimer);
|
|
396
|
+
this.#idleTimer = null;
|
|
397
|
+
this.#idleTimerSession = null;
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
// ——— management API surface (SPEC §11) ———————————————————————————————
|
|
401
|
+
/** Explicit restore for the service API (SPEC §11 `restore`). */
|
|
402
|
+
async restoreNow(sessionId) {
|
|
403
|
+
return this.#mutex.runExclusive(async () => {
|
|
404
|
+
const runtime = this.#sessions.get(sessionId);
|
|
405
|
+
if (runtime === undefined) {
|
|
406
|
+
return { kind: "cold", sessionId, tokens: null, bytes: null, durationMs: null, error: "no known route for session" };
|
|
407
|
+
}
|
|
408
|
+
if (this.#breaker.isOpen(this.#now())) {
|
|
409
|
+
return { kind: "cold-fallback", sessionId, tokens: null, bytes: null, durationMs: null, error: "circuit open" };
|
|
410
|
+
}
|
|
411
|
+
const identity = this.#identityFor(sessionId, runtime.route);
|
|
412
|
+
return this.#prepareSession(sessionId, identity);
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
/** Explicit save for the service API (SPEC §11 `save`). */
|
|
416
|
+
async saveNow(sessionId) {
|
|
417
|
+
return this.#mutex.runExclusive(async () => {
|
|
418
|
+
if (!this.#policy.shouldCheckpoint(this.#sessions.get(sessionId), "manual")) {
|
|
419
|
+
return { kind: "skipped-clean", sessionId, revision: 0, bytes: null, error: "nothing to save" };
|
|
420
|
+
}
|
|
421
|
+
return this.#saveOwnedSession(sessionId, "manual");
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
/** Invalidate every snapshot of a session without deleting data (§31). */
|
|
425
|
+
async invalidate(sessionId, reason = "EXPLICIT") {
|
|
426
|
+
await this.#mutex.runExclusive(async () => {
|
|
427
|
+
const runtime = this.#sessions.get(sessionId);
|
|
428
|
+
if (runtime !== undefined)
|
|
429
|
+
runtime.lifecycle = "invalid";
|
|
430
|
+
if (this.#slot.ownerSessionId === sessionId) {
|
|
431
|
+
await this.#eraseSlotBestEffort();
|
|
432
|
+
this.#slot.ownerSessionId = null;
|
|
433
|
+
this.#slot.state = "idle";
|
|
434
|
+
}
|
|
435
|
+
await this.#repository.invalidateSession(sessionId, reason, this.#iso());
|
|
436
|
+
this.#logger.info("kv.snapshot.invalidated", { sessionId, reason });
|
|
437
|
+
});
|
|
438
|
+
}
|
|
439
|
+
/** Purge all metadata of a session (SPEC §11 `purge`). */
|
|
440
|
+
async purge(sessionId) {
|
|
441
|
+
await this.#mutex.runExclusive(async () => {
|
|
442
|
+
if (this.#slot.ownerSessionId === sessionId) {
|
|
443
|
+
await this.#eraseSlotBestEffort();
|
|
444
|
+
this.#slot.ownerSessionId = null;
|
|
445
|
+
this.#slot.state = "idle";
|
|
446
|
+
}
|
|
447
|
+
await this.#repository.removeSession(sessionId);
|
|
448
|
+
this.#sessions.delete(sessionId);
|
|
449
|
+
});
|
|
450
|
+
}
|
|
451
|
+
/** Probe the backend (SPEC §34); resets the breaker on success. */
|
|
452
|
+
async probeBackend() {
|
|
453
|
+
try {
|
|
454
|
+
const capabilities = await this.#backend.probe();
|
|
455
|
+
this.#breaker.recordSuccess();
|
|
456
|
+
this.#logger.info("kv.backend.ready", { slots: capabilities.slotIds.length });
|
|
457
|
+
return { healthy: true, slotIds: capabilities.slotIds, error: null };
|
|
458
|
+
}
|
|
459
|
+
catch (error) {
|
|
460
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
461
|
+
this.#logger.warn("kv.backend.unavailable", { error: message });
|
|
462
|
+
return { healthy: false, slotIds: [], error: message };
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
/** Shutdown (SPEC §58): stop work, cancel timers, final checkpoint. */
|
|
466
|
+
async dispose() {
|
|
467
|
+
this.#disposed = true;
|
|
468
|
+
this.#cancelIdleTimer();
|
|
469
|
+
await this.flushOwned("shutdown").catch(() => undefined);
|
|
470
|
+
}
|
|
471
|
+
// ——— internals ———————————————————————————————————————————————————————
|
|
472
|
+
#ensureRuntime(sessionId, route) {
|
|
473
|
+
const existing = this.#sessions.get(sessionId);
|
|
474
|
+
if (existing !== undefined) {
|
|
475
|
+
existing.route = { provider: route.provider, model: route.model };
|
|
476
|
+
return existing;
|
|
477
|
+
}
|
|
478
|
+
const runtime = createSessionRuntime(sessionId, route);
|
|
479
|
+
this.#sessions.set(sessionId, runtime);
|
|
480
|
+
return runtime;
|
|
481
|
+
}
|
|
482
|
+
#requireRuntime(sessionId) {
|
|
483
|
+
const runtime = this.#sessions.get(sessionId);
|
|
484
|
+
if (runtime === undefined) {
|
|
485
|
+
throw new KvPersistError("KV_INVARIANT", `missing session runtime for ${abbreviateSessionId(sessionId)}`);
|
|
486
|
+
}
|
|
487
|
+
return runtime;
|
|
488
|
+
}
|
|
489
|
+
#identityFor(sessionId, route) {
|
|
490
|
+
return buildSnapshotIdentity({
|
|
491
|
+
sessionId,
|
|
492
|
+
route: { provider: route.provider, model: route.model },
|
|
493
|
+
baseURL: this.#config.baseURL,
|
|
494
|
+
runtimeKey: this.#config.runtimeKey,
|
|
495
|
+
});
|
|
496
|
+
}
|
|
497
|
+
#assignSlot(sessionId, state) {
|
|
498
|
+
const switched = this.#slot.ownerSessionId !== sessionId;
|
|
499
|
+
this.#slot.ownerSessionId = sessionId;
|
|
500
|
+
this.#slot.state = state;
|
|
501
|
+
this.#slot.snapshotRevision = null;
|
|
502
|
+
this.#slot.lastUsedAt = this.#now();
|
|
503
|
+
if (switched)
|
|
504
|
+
this.#metrics.counters.slotSwitches += 1;
|
|
505
|
+
}
|
|
506
|
+
async #eraseSlotBestEffort() {
|
|
507
|
+
try {
|
|
508
|
+
await this.#backend.eraseSlot(this.#slot.id);
|
|
509
|
+
this.#metrics.counters.erases += 1;
|
|
510
|
+
}
|
|
511
|
+
catch (error) {
|
|
512
|
+
// Cold path must continue even when the erase fails (SPEC §32, §53).
|
|
513
|
+
this.#breaker.recordFailure(this.#now());
|
|
514
|
+
this.#logger.warn("kv.slot.erase_failed", {
|
|
515
|
+
slot: this.#slot.id,
|
|
516
|
+
error: error instanceof Error ? error.message : String(error),
|
|
517
|
+
});
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
async #findCompatibleManifest(identity) {
|
|
521
|
+
try {
|
|
522
|
+
return await this.#repository.findCompatible(identity);
|
|
523
|
+
}
|
|
524
|
+
catch (error) {
|
|
525
|
+
// A malformed manifest must not crash the request path (SPEC §32).
|
|
526
|
+
this.#logger.warn("kv.snapshot.manifest_invalid", {
|
|
527
|
+
error: error instanceof Error ? error.message : String(error),
|
|
528
|
+
});
|
|
529
|
+
return null;
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
/** The slot content may have changed unobserved; drop ownership bookkeeping. */
|
|
533
|
+
#loseSlotTracking() {
|
|
534
|
+
this.#slot.ownerSessionId = null;
|
|
535
|
+
this.#slot.state = "unknown";
|
|
536
|
+
this.#slot.snapshotRevision = null;
|
|
537
|
+
}
|
|
538
|
+
#iso() {
|
|
539
|
+
return new Date(this.#now()).toISOString();
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
//# sourceMappingURL=coordinator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coordinator.js","sourceRoot":"","sources":["../../src/coordinator/coordinator.ts"],"names":[],"mappings":"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"}
|