@lensmcp/cluster 1.16.18 → 1.16.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -15,8 +15,9 @@ export interface LensChildren {
15
15
  * everything"): spawn each app's vite (+ capture) in the workspace's OWN root + event bus, on a
16
16
  * collision-safe port, and point its route target at that port. Returns a reaper for unregister. */
17
17
  hostWorkspaceApps(fragment: WorkspaceFragment): () => void;
18
- /** Reap all managed children (called from `stop()`). */
19
- reapAll(): void;
18
+ /** Reap all managed children (called from `stop()`): SIGTERM, a grace window, then SIGKILL any survivor
19
+ * (vite ignores SIGTERM → would orphan when the daemon exits). Async so `stop()` awaits the escalation. */
20
+ reapAll(): Promise<void>;
20
21
  }
21
22
  export declare function createLensChildren(rt: GatewayRuntime, obs: Observability, options: GatewayRuntimeOptions): LensChildren;
22
23
  //# sourceMappingURL=lens-children.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"lens-children.d.ts","sourceRoot":"","sources":["../../../../../../libs/cluster/src/executors/gateway/runtime/lens-children.ts"],"names":[],"mappings":"AAQA,OAAO,EAIL,KAAK,UAAU,EAChB,MAAM,kCAAkC,CAAC;AAG1C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,OAAO,KAAK,EAAE,cAAc,EAAE,qBAAqB,EAAuB,MAAM,SAAS,CAAC;AAQ1F,OAAO,EAA0B,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAM7E,MAAM,WAAW,YAAY;IAC3B,iBAAiB,EAAE,UAAU,CAAC;IAC9B;iFAC6E;IAC7E,qBAAqB,IAAI,IAAI,CAAC;IAC9B;;6GAEyG;IACzG,sBAAsB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC;IAC9E;;yGAEqG;IACrG,iBAAiB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,MAAM,IAAI,CAAC;IAC3D,wDAAwD;IACxD,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,cAAc,EAAE,GAAG,EAAE,aAAa,EAAE,OAAO,EAAE,qBAAqB,GAAG,YAAY,CAySvH"}
1
+ {"version":3,"file":"lens-children.d.ts","sourceRoot":"","sources":["../../../../../../libs/cluster/src/executors/gateway/runtime/lens-children.ts"],"names":[],"mappings":"AAQA,OAAO,EAIL,KAAK,UAAU,EAChB,MAAM,kCAAkC,CAAC;AAG1C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,OAAO,KAAK,EAAE,cAAc,EAAE,qBAAqB,EAAuB,MAAM,SAAS,CAAC;AAQ1F,OAAO,EAA0B,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAM7E,MAAM,WAAW,YAAY;IAC3B,iBAAiB,EAAE,UAAU,CAAC;IAC9B;iFAC6E;IAC7E,qBAAqB,IAAI,IAAI,CAAC;IAC9B;;6GAEyG;IACzG,sBAAsB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC;IAC9E;;yGAEqG;IACrG,iBAAiB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,MAAM,IAAI,CAAC;IAC3D;gHAC4G;IAC5G,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AAED,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,cAAc,EAAE,GAAG,EAAE,aAAa,EAAE,OAAO,EAAE,qBAAqB,GAAG,YAAY,CAmTvH"}
@@ -315,17 +315,34 @@ function createLensChildren(rt, obs, options) {
315
315
  usedAppPorts.delete(p);
316
316
  };
317
317
  };
318
- const reapAll = () => {
318
+ const reapAll = async (graceMs = 2500) => {
319
319
  if (lensSweeper) {
320
320
  clearInterval(lensSweeper);
321
321
  lensSweeper = undefined;
322
322
  }
323
- for (const c of lensChildren) {
323
+ const kids = [...lensChildren];
324
+ for (const c of kids) {
324
325
  try {
325
326
  c.kill('SIGTERM');
326
327
  }
327
328
  catch { /* already gone */ }
328
329
  }
330
+ // Grace, then SIGKILL any survivor — vite ignores SIGTERM, so without this it ORPHANS (reparents to
331
+ // ppid 1) when the daemon exits, keeping its port held (5173/4200/…). Poll so we escalate only for the
332
+ // stragglers and wait no longer than needed.
333
+ const alive = (c) => c.exitCode === null && c.signalCode === null;
334
+ const deadline = Date.now() + graceMs;
335
+ while (Date.now() < deadline && kids.some(alive)) {
336
+ await new Promise((r) => setTimeout(r, 100));
337
+ }
338
+ for (const c of kids) {
339
+ if (alive(c)) {
340
+ try {
341
+ c.kill('SIGKILL');
342
+ }
343
+ catch { /* already gone */ }
344
+ }
345
+ }
329
346
  };
330
347
  return { spawnManagedChild, bootSingletonsAndApps, hostWorkspaceDashboard, hostWorkspaceApps, reapAll };
331
348
  }
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../../../../libs/cluster/src/executors/gateway/runtime/server.ts"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAkB,qBAAqB,EAAsB,MAAM,SAAS,CAAC;AAkDxH,wBAAsB,YAAY,CAChC,OAAO,EAAE,qBAAqB,EAC9B,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,aAAa,CAAC,CAkPxB"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../../../../libs/cluster/src/executors/gateway/runtime/server.ts"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAkB,qBAAqB,EAAsB,MAAM,SAAS,CAAC;AAkDxH,wBAAsB,YAAY,CAChC,OAAO,EAAE,qBAAqB,EAC9B,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,aAAa,CAAC,CAmPxB"}
@@ -305,9 +305,10 @@ async function startGateway(options, context) {
305
305
  (0, workspace_registry_1.unregisterWorkspace)(wsKey); // drop this workspace from the global chooser registry (graceful stop)
306
306
  for (const svc of services)
307
307
  svcLayer.killSpawned(svc, 'gateway shutdown');
308
- // Reap the lens-mode managed children (dashboard + MCP singletons + each
309
- // `lens:true` app's Vite/capture) same teardown as the pod services.
310
- lens.reapAll();
308
+ // Reap the lens-mode managed children (dashboard + MCP singletons + each `lens:true` app's Vite/capture)
309
+ // SIGTERM grace SIGKILL, awaited, so a SIGTERM-ignoring vite is gone BEFORE the daemon exits
310
+ // (otherwise it orphans + keeps its port). Same teardown as the pod services.
311
+ await lens.reapAll();
311
312
  await Promise.all(servers.map((s) => new Promise((r) => s.close(() => r()))));
312
313
  proxyLayer.closeProxy();
313
314
  proxyLayer.destroyAgents(); // release pooled upstream sockets
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lensmcp/cluster",
3
- "version": "1.16.18",
3
+ "version": "1.16.19",
4
4
  "description": "Run your Nx workspace as a local production cluster: pods on unix sockets with true HMR, one https gateway with per-project domains, scale-from-zero, autoscale, idle-kill, local-CA TLS — observed by the LensMCP lens.",
5
5
  "main": "./index.js",
6
6
  "types": "./index.d.ts",
@@ -65,8 +65,8 @@
65
65
  }
66
66
  },
67
67
  "dependencies": {
68
- "@lensmcp/node-instrumentation": "1.16.18",
69
- "@lensmcp/nx-plugin": "1.16.18",
68
+ "@lensmcp/node-instrumentation": "1.16.19",
69
+ "@lensmcp/nx-plugin": "1.16.19",
70
70
  "fork-ts-checker-webpack-plugin": "^9.0.0",
71
71
  "glob": "^11.0.0",
72
72
  "http-proxy": "^1.18.0",