UNPKG

@juspay/neurolink

Version:

The pipe layer of an AI nervous system: one interface connecting provider neurons to your application, across three inference types — generate, stream and decide. `decide` returns typed, calibrated judgements from a non-generative model (~400ms, ~$0.00002

220 lines (219 loc) • 8.26 kB
import { execFile } from "node:child_process"; import { randomUUID } from "node:crypto"; import { readFileSync, realpathSync } from "node:fs"; import { lstat, readdir, rename, rm } from "node:fs/promises"; import { isAbsolute, join, relative, resolve, sep } from "node:path"; import { promisify } from "node:util"; import { readProxyPackageSelection } from "./globalInstaller.js"; const execFileAsync = promisify(execFile); // Only the names globalInstaller.ts generates: `<version>`, // `<version>-release-<uuid>` and `<version>-polyfills-<digest>-<uuid>`. Anything // else in the store (a hand-made `-official` copy, an in-flight `.install-*` // staging tree) is not ours to delete. const GENERATED_BUILD_NAME = /^\d+\.\d+\.\d+(?:-release-[0-9a-f-]{36}|-polyfills-[0-9a-f]{16}-[0-9a-f-]{36})?$/; const TOMBSTONE_PREFIX = ".prune-"; const DEFAULT_MIN_AGE_MS = 60 * 60_000; function entryScriptOf(value) { return typeof value === "object" && value !== null && "entryScript" in value && typeof value.entryScript === "string" ? value.entryScript : undefined; } function canonical(path) { try { return realpathSync(path); } catch { return path; } } /** First path segment below the store, i.e. the build directory a file lives in. */ function buildDirectoryOf(storeRoot, path) { const rel = relative(storeRoot, canonical(path)); if (!rel || rel.startsWith("..") || isAbsolute(rel)) { return null; } return rel.split(sep)[0] ?? null; } /** * Read selections.json without validating the builds it names: a build that * failed validation once must still count as referenced, not as garbage. */ function rawSelectedEntryScripts(packagesDir) { try { const state = JSON.parse(readFileSync(join(packagesDir, "selections.json"), "utf8")); if (typeof state !== "object" || state === null) { return []; } return [ "active" in state ? entryScriptOf(state.active) : undefined, "previous" in state ? entryScriptOf(state.previous) : undefined, ].filter((entry) => entry !== undefined); } catch { return []; } } async function listProcessCommandLines() { if (process.platform === "win32") { return null; } try { const { stdout } = await execFileAsync("ps", ["-axo", "command="], { maxBuffer: 64 * 1024 * 1024, timeout: 10_000, }); return stdout.split("\n"); } catch { return null; } } function mentionsDirectory(line, directory) { return (line.includes(`${directory}${sep}`) || line.includes(`${directory} `) || line.endsWith(directory)); } /** * Keep the selected pair (active and rollback) and remove every other build the * installer generated. Nothing is removed unless the active selection is valid, * the live process list could be read, and the build is neither referenced by a * running process nor recently written. */ export async function pruneProxyPackages(options) { const skip = (reason) => ({ skipped: reason, removed: [], retained: [], failed: [], }); let storeRoot; try { storeRoot = realpathSync(options.packagesDir); } catch { return skip("package store does not exist"); } const buildDirectories = (entryScripts) => new Set(entryScripts .filter((entry) => entry !== undefined) .map((entry) => buildDirectoryOf(storeRoot, entry)) .filter((name) => name !== null)); // Read again before every removal, not once: a pass can outlive the selection // it started from. Null means the active selection no longer validates. const readSelected = () => { const active = readProxyPackageSelection(options.packagesDir); if (!active) { return null; } return buildDirectories([ active.entryScript, readProxyPackageSelection(options.packagesDir, true)?.entryScript, ...rawSelectedEntryScripts(options.packagesDir), ]); }; const selected = readSelected(); if (!selected) { return skip("no validated active package selection"); } const running = buildDirectories([options.currentEntryScript]); const entries = await readdir(storeRoot, { withFileTypes: true }); const failed = []; // A pass killed between rename and rm leaves a tombstone; nothing else reads it. for (const entry of entries) { if (!options.dryRun && entry.isDirectory() && entry.name.startsWith(TOMBSTONE_PREFIX)) { await rm(join(storeRoot, entry.name), { recursive: true, force: true, }).catch((error) => { failed.push({ name: entry.name, message: String(error) }); }); } } const candidates = entries .filter((entry) => entry.isDirectory() && GENERATED_BUILD_NAME.test(entry.name)) .map((entry) => entry.name) .sort(); const unselected = candidates.filter((name) => !selected.has(name)); const processLines = unselected.length ? await (options.listProcessCommandLines ?? listProcessCommandLines)() : []; if (processLines === null) { return skip("running processes could not be enumerated"); } const retained = candidates .filter((name) => selected.has(name)) .map((name) => ({ name, reason: "selected" })); const removed = []; const now = options.now ?? Date.now(); const minAgeMs = options.minAgeMs ?? DEFAULT_MIN_AGE_MS; // A process may name the store through a symlinked spelling (/var vs // /private/var), so match the path as configured as well as the real one. const storeSpellings = [ ...new Set([storeRoot, resolve(options.packagesDir)]), ]; for (const name of unselected) { const directory = join(storeRoot, name); const retain = (reason) => { retained.push({ name, reason }); }; if (running.has(name) || processLines.some((line) => storeSpellings.some((store) => mentionsDirectory(line, join(store, name))))) { retain("in-use"); continue; } try { const stats = await lstat(directory); if (now - Math.max(stats.mtimeMs, stats.ctimeMs) < minAgeMs) { retain("recent"); continue; } if (options.dryRun) { removed.push(name); continue; } // The only thing left between this check and the rename is the rename. A // replacement updater may have selected this build, or taken over, since // the pass began. const latest = readSelected(); if (!latest) { return { skipped: "package selection became invalid during the pass", removed, retained, failed, }; } if (latest.has(name)) { retain("selected"); continue; } if (options.isCurrentOwner && !options.isCurrentOwner()) { return { skipped: "update ownership changed during the pass", removed, retained, failed, }; } // Rename first: a half-deleted directory under its real name would pass // installStagedProxyPackage's existsSync() shortcut and then fail validation. const tombstone = join(storeRoot, `${TOMBSTONE_PREFIX}${name}-${randomUUID()}`); await rename(directory, tombstone); removed.push(name); await rm(tombstone, { recursive: true, force: true }); } catch (error) { if (error.code !== "ENOENT") { failed.push({ name, message: error instanceof Error ? error.message : String(error), }); } } } return { removed, retained, failed }; }