Files
llama-watch/src/lib/inflight-tracker.ts
T

62 lines
1.7 KiB
TypeScript

export interface InflightRequest {
id?: string;
model: string;
req_path?: string;
method?: string;
timestamp?: string;
elapsed_ms?: number;
}
export interface ModelState {
id: string;
state: string;
}
export type FeedEvent =
| { type: "inflight"; operation: "snapshot" | "add"; requests: InflightRequest[] }
| { type: "inflight"; operation: "remove"; id: string }
| { type: "activity"; id: number }
| { type: "modelStatus"; models: ModelState[] };
export type ModelRuntimeState = "stopped" | "loading" | "ready";
export class InflightTracker {
private requests = new Map<string, string>();
private states = new Map<string, ModelRuntimeState>();
apply(event: FeedEvent): void {
if (event.type === "inflight") {
if (event.operation === "snapshot") {
this.requests = new Map<string, string>();
for (const r of event.requests) if (r.id) this.requests.set(r.id, r.model);
} else if (event.operation === "add") {
for (const r of event.requests) if (r.id) this.requests.set(r.id, r.model);
} else if (event.operation === "remove") {
this.requests.delete(event.id);
}
} else if (event.type === "modelStatus") {
for (const m of event.models) this.states.set(m.id, normalizeState(m.state));
}
}
count(modelId: string): number {
let n = 0;
for (const model of this.requests.values()) if (model === modelId) n++;
return n;
}
total(): number {
return this.requests.size;
}
state(modelId: string): ModelRuntimeState | undefined {
return this.states.get(modelId);
}
}
function normalizeState(state: string): ModelRuntimeState {
if (state === "ready") return "ready";
if (state === "loading") return "loading";
return "stopped";
}