mirror of https://github.com/openclaw/openclaw.git
100 lines
2.3 KiB
TypeScript
100 lines
2.3 KiB
TypeScript
import type { AcpRuntime, AcpRuntimeHandle, AcpRuntimeSessionMode } from "../runtime/types.js";
|
|
|
|
export type CachedRuntimeState = {
|
|
runtime: AcpRuntime;
|
|
handle: AcpRuntimeHandle;
|
|
backend: string;
|
|
agent: string;
|
|
mode: AcpRuntimeSessionMode;
|
|
cwd?: string;
|
|
appliedControlSignature?: string;
|
|
};
|
|
|
|
type RuntimeCacheEntry = {
|
|
state: CachedRuntimeState;
|
|
lastTouchedAt: number;
|
|
};
|
|
|
|
export type CachedRuntimeSnapshot = {
|
|
actorKey: string;
|
|
state: CachedRuntimeState;
|
|
lastTouchedAt: number;
|
|
idleMs: number;
|
|
};
|
|
|
|
export class RuntimeCache {
|
|
private readonly cache = new Map<string, RuntimeCacheEntry>();
|
|
|
|
size(): number {
|
|
return this.cache.size;
|
|
}
|
|
|
|
has(actorKey: string): boolean {
|
|
return this.cache.has(actorKey);
|
|
}
|
|
|
|
get(
|
|
actorKey: string,
|
|
params: {
|
|
touch?: boolean;
|
|
now?: number;
|
|
} = {},
|
|
): CachedRuntimeState | null {
|
|
const entry = this.cache.get(actorKey);
|
|
if (!entry) {
|
|
return null;
|
|
}
|
|
if (params.touch !== false) {
|
|
entry.lastTouchedAt = params.now ?? Date.now();
|
|
}
|
|
return entry.state;
|
|
}
|
|
|
|
peek(actorKey: string): CachedRuntimeState | null {
|
|
return this.get(actorKey, { touch: false });
|
|
}
|
|
|
|
getLastTouchedAt(actorKey: string): number | null {
|
|
return this.cache.get(actorKey)?.lastTouchedAt ?? null;
|
|
}
|
|
|
|
set(
|
|
actorKey: string,
|
|
state: CachedRuntimeState,
|
|
params: {
|
|
now?: number;
|
|
} = {},
|
|
): void {
|
|
this.cache.set(actorKey, {
|
|
state,
|
|
lastTouchedAt: params.now ?? Date.now(),
|
|
});
|
|
}
|
|
|
|
clear(actorKey: string): void {
|
|
this.cache.delete(actorKey);
|
|
}
|
|
|
|
snapshot(params: { now?: number } = {}): CachedRuntimeSnapshot[] {
|
|
const now = params.now ?? Date.now();
|
|
const entries: CachedRuntimeSnapshot[] = [];
|
|
for (const [actorKey, entry] of this.cache.entries()) {
|
|
entries.push({
|
|
actorKey,
|
|
state: entry.state,
|
|
lastTouchedAt: entry.lastTouchedAt,
|
|
idleMs: Math.max(0, now - entry.lastTouchedAt),
|
|
});
|
|
}
|
|
return entries;
|
|
}
|
|
|
|
collectIdleCandidates(params: { maxIdleMs: number; now?: number }): CachedRuntimeSnapshot[] {
|
|
if (!Number.isFinite(params.maxIdleMs) || params.maxIdleMs <= 0) {
|
|
return [];
|
|
}
|
|
const now = params.now ?? Date.now();
|
|
return this.snapshot({ now }).filter((entry) => entry.idleMs >= params.maxIdleMs);
|
|
}
|
|
}
|