import fs from "node:fs"; import { writeJsonAtomic } from "../lib/jsonFile-server"; import type { Paths } from "../lib/paths"; // Persisted "default" worker arrangement. Unlike the in-memory worker pool // (whose runtime enable/disable/drain state is wiped on every server restart), // this small file survives restarts: it records the set of worker ids that // should start ENABLED on the next launch. Any configured worker NOT listed // here starts disabled. It is written only by the explicit Workers-page "Set as // default" button (not on every runtime toggle) and read once by the worker // pool on first use. // // File absent = no default has been set; the pool keeps its current behavior of // seeding runtime state from each worker's persisted `enabled` flag. File // present = the pool overlays this set over that seed at launch. // // This is the worker analogue of common/jobs/syncSchedulerState.ts. The read is // synchronous (like getSettings) so the synchronous WorkerPool can call it // during lazy init; the write is async (atomic tmp + rename) from the server // action. export type WorkerDefaults = { // Worker ids that should start enabled at launch. Order is not significant. enabledWorkerIds: string[]; }; // Read the default arrangement, tolerating a missing/corrupt file by returning // null (meaning "no default set — fall back to settings.enabled"). The id list // is coerced to a deduped string[] so a hand-edited file can't crash init. export function readWorkerDefaults(paths: Paths): WorkerDefaults | null { let raw: unknown; try { raw = JSON.parse(fs.readFileSync(paths.workerDefaultsFile, "utf8")); } catch { return null; } if (!raw || typeof raw !== "object") return null; const r = raw as Record; if (!Array.isArray(r.enabledWorkerIds)) return null; const seen = new Set(); for (const id of r.enabledWorkerIds) { if (typeof id === "string" && id) seen.add(id); } return { enabledWorkerIds: Array.from(seen) }; } // Write the default arrangement atomically (tmp file + rename), creating the // .workers dir on first use. Ids are sanitized to a deduped string[]. export async function writeWorkerDefaults( paths: Paths, enabledWorkerIds: string[], ): Promise { const seen = new Set(); for (const id of enabledWorkerIds) { if (typeof id === "string" && id) seen.add(id); } const out: WorkerDefaults = { enabledWorkerIds: Array.from(seen) }; await writeJsonAtomic(paths.workerDefaultsFile, out, { mkdir: true }); }