mirror of https://github.com/openclaw/openclaw.git
refactor(sandbox): dedupe prune loops
This commit is contained in:
parent
d4476c6899
commit
5457f6e7e4
|
|
@ -8,69 +8,80 @@ import {
|
|||
readRegistry,
|
||||
removeBrowserRegistryEntry,
|
||||
removeRegistryEntry,
|
||||
type SandboxBrowserRegistryEntry,
|
||||
type SandboxRegistryEntry,
|
||||
} from "./registry.js";
|
||||
|
||||
let lastPruneAtMs = 0;
|
||||
|
||||
async function pruneSandboxContainers(cfg: SandboxConfig) {
|
||||
const now = Date.now();
|
||||
type PruneableRegistryEntry = Pick<
|
||||
SandboxRegistryEntry,
|
||||
"containerName" | "createdAtMs" | "lastUsedAtMs"
|
||||
>;
|
||||
|
||||
function shouldPruneSandboxEntry(cfg: SandboxConfig, now: number, entry: PruneableRegistryEntry) {
|
||||
const idleHours = cfg.prune.idleHours;
|
||||
const maxAgeDays = cfg.prune.maxAgeDays;
|
||||
if (idleHours === 0 && maxAgeDays === 0) {
|
||||
return false;
|
||||
}
|
||||
const idleMs = now - entry.lastUsedAtMs;
|
||||
const ageMs = now - entry.createdAtMs;
|
||||
return (
|
||||
(idleHours > 0 && idleMs > idleHours * 60 * 60 * 1000) ||
|
||||
(maxAgeDays > 0 && ageMs > maxAgeDays * 24 * 60 * 60 * 1000)
|
||||
);
|
||||
}
|
||||
|
||||
async function pruneSandboxRegistryEntries<TEntry extends PruneableRegistryEntry>(params: {
|
||||
cfg: SandboxConfig;
|
||||
read: () => Promise<{ entries: TEntry[] }>;
|
||||
remove: (containerName: string) => Promise<void>;
|
||||
onRemoved?: (entry: TEntry) => Promise<void>;
|
||||
}) {
|
||||
const now = Date.now();
|
||||
if (params.cfg.prune.idleHours === 0 && params.cfg.prune.maxAgeDays === 0) {
|
||||
return;
|
||||
}
|
||||
const registry = await readRegistry();
|
||||
const registry = await params.read();
|
||||
for (const entry of registry.entries) {
|
||||
const idleMs = now - entry.lastUsedAtMs;
|
||||
const ageMs = now - entry.createdAtMs;
|
||||
if (
|
||||
(idleHours > 0 && idleMs > idleHours * 60 * 60 * 1000) ||
|
||||
(maxAgeDays > 0 && ageMs > maxAgeDays * 24 * 60 * 60 * 1000)
|
||||
) {
|
||||
try {
|
||||
await execDocker(["rm", "-f", entry.containerName], {
|
||||
allowFailure: true,
|
||||
});
|
||||
} catch {
|
||||
// ignore prune failures
|
||||
} finally {
|
||||
await removeRegistryEntry(entry.containerName);
|
||||
}
|
||||
if (!shouldPruneSandboxEntry(params.cfg, now, entry)) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
await execDocker(["rm", "-f", entry.containerName], {
|
||||
allowFailure: true,
|
||||
});
|
||||
} catch {
|
||||
// ignore prune failures
|
||||
} finally {
|
||||
await params.remove(entry.containerName);
|
||||
await params.onRemoved?.(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function pruneSandboxContainers(cfg: SandboxConfig) {
|
||||
await pruneSandboxRegistryEntries<SandboxRegistryEntry>({
|
||||
cfg,
|
||||
read: readRegistry,
|
||||
remove: removeRegistryEntry,
|
||||
});
|
||||
}
|
||||
|
||||
async function pruneSandboxBrowsers(cfg: SandboxConfig) {
|
||||
const now = Date.now();
|
||||
const idleHours = cfg.prune.idleHours;
|
||||
const maxAgeDays = cfg.prune.maxAgeDays;
|
||||
if (idleHours === 0 && maxAgeDays === 0) {
|
||||
return;
|
||||
}
|
||||
const registry = await readBrowserRegistry();
|
||||
for (const entry of registry.entries) {
|
||||
const idleMs = now - entry.lastUsedAtMs;
|
||||
const ageMs = now - entry.createdAtMs;
|
||||
if (
|
||||
(idleHours > 0 && idleMs > idleHours * 60 * 60 * 1000) ||
|
||||
(maxAgeDays > 0 && ageMs > maxAgeDays * 24 * 60 * 60 * 1000)
|
||||
) {
|
||||
try {
|
||||
await execDocker(["rm", "-f", entry.containerName], {
|
||||
allowFailure: true,
|
||||
});
|
||||
} catch {
|
||||
// ignore prune failures
|
||||
} finally {
|
||||
await removeBrowserRegistryEntry(entry.containerName);
|
||||
const bridge = BROWSER_BRIDGES.get(entry.sessionKey);
|
||||
if (bridge?.containerName === entry.containerName) {
|
||||
await stopBrowserBridgeServer(bridge.bridge.server).catch(() => undefined);
|
||||
BROWSER_BRIDGES.delete(entry.sessionKey);
|
||||
}
|
||||
await pruneSandboxRegistryEntries<SandboxBrowserRegistryEntry>({
|
||||
cfg,
|
||||
read: readBrowserRegistry,
|
||||
remove: removeBrowserRegistryEntry,
|
||||
onRemoved: async (entry) => {
|
||||
const bridge = BROWSER_BRIDGES.get(entry.sessionKey);
|
||||
if (bridge?.containerName === entry.containerName) {
|
||||
await stopBrowserBridgeServer(bridge.bridge.server).catch(() => undefined);
|
||||
BROWSER_BRIDGES.delete(entry.sessionKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export async function maybePruneSandboxes(cfg: SandboxConfig) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue