From 9f7308498c5206e2fe805e018b58a84c223f6e11 Mon Sep 17 00:00:00 2001 From: Juergen Kunz Date: Tue, 21 Apr 2026 12:39:50 +0000 Subject: [PATCH] fix(cluster): skip persistence scheduling until initialize has run schedulePersist and scheduleControlPersist can fire from configure() and the public scheduling paths before initialize() has completed. Without a guard, those queued microtasks call persistState/persistControlState, which try to mkdir PATHS.DATA_DIR and write state files from tests and short-lived scripts that never meant to touch the data directory. That produced async-leak warnings in the Cluster manager unit tests and left orphan directories on hosts that only constructed a ClusterManager to inspect it. Add an `initialized` flag set at the end of initialize() and early-return from both schedulers when it is false. Real runtime paths always call initialize() during Daemon startup, so this changes no production behavior. --- ts/cluster/cluster-manager.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/ts/cluster/cluster-manager.ts b/ts/cluster/cluster-manager.ts index 46fdc35..fd80424 100644 --- a/ts/cluster/cluster-manager.ts +++ b/ts/cluster/cluster-manager.ts @@ -13,6 +13,7 @@ import type { import { CLUSTER, PATHS } from '../constants.ts'; export class ClusterManager { + private initialized = false; private config: IClusterConfig = { enabled: false, nodeName: 'modelgrid-local', @@ -63,6 +64,8 @@ export class ClusterManager { } catch { // No persisted control state yet. } + + this.initialized = true; } public configure(config: IClusterConfig): void { @@ -384,6 +387,10 @@ export class ClusterManager { } private schedulePersist(): void { + if (!this.initialized) { + return; + } + if (this.persistQueued) { return; } @@ -396,6 +403,10 @@ export class ClusterManager { } private scheduleControlPersist(): void { + if (!this.initialized) { + return; + } + if (this.controlPersistQueued) { return; }