@lensmcp/cluster 1.16.11 → 1.16.12

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.
Files changed (2) hide show
  1. package/main.devserver.js +14 -5
  2. package/package.json +3 -3
package/main.devserver.js CHANGED
@@ -717,7 +717,20 @@ else {
717
717
  }
718
718
  console.error(`[parent] public server error:`, err);
719
719
  });
720
- server.listen(publicPort, async () => {
720
+ // The child pods — which serve on the unix sockets the gateway routes to — are the REAL serving path.
721
+ // Fork them UNCONDITIONALLY, BEFORE (and independent of) the vestigial public TCP port. This block used
722
+ // to live in the public-`listen` SUCCESS callback, so a public-port EADDRINUSE (a cross-workspace clash —
723
+ // e.g. two workspaces' services on the same default port — or a not-yet-released prior instance) meant
724
+ // the callback never fired → NO pods were forked → with no TCP server bound the parent's event loop
725
+ // emptied and it exited code=0 → the supervisor respawned it → a zombie respawn storm (the "loser of a
726
+ // public-port race gets stuck with 0 pods" bug). Under the gateway EVERYTHING reaches this service
727
+ // through the socket pool, so pod creation must NEVER be gated on the vestigial TCP port. The pods'
728
+ // IPC channels keep the parent alive even when no TCP port ever binds.
729
+ await ensurePoolSize(CHILD_COUNT);
730
+ for (const name of WORKER_NAMES) {
731
+ spawnWorkerProcess(name);
732
+ }
733
+ server.listen(publicPort, () => {
721
734
  const scheme = GATEWAY_HTTPS ? 'https' : 'http';
722
735
  console.log(`[parent] Listening on ${scheme}://localhost:${publicPort}`);
723
736
  if (SERVICE_PREFIX) {
@@ -734,10 +747,6 @@ else {
734
747
  console.log(`[parent] sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain ${gatewayCaPath}`);
735
748
  }
736
749
  console.log(`POST ${scheme}://localhost:${publicPort}/webpack/reload to trigger rolling swap/respawn`);
737
- await ensurePoolSize(CHILD_COUNT);
738
- for (const name of WORKER_NAMES) {
739
- spawnWorkerProcess(name);
740
- }
741
750
  });
742
751
  // Internal service-to-service port: plain http, straight to the children —
743
752
  // NO gateway routes, NO gateway middleware (JWT etc.). Peers call this
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lensmcp/cluster",
3
- "version": "1.16.11",
3
+ "version": "1.16.12",
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.11",
69
- "@lensmcp/nx-plugin": "1.16.11",
68
+ "@lensmcp/node-instrumentation": "1.16.12",
69
+ "@lensmcp/nx-plugin": "1.16.12",
70
70
  "fork-ts-checker-webpack-plugin": "^9.0.0",
71
71
  "glob": "^11.0.0",
72
72
  "http-proxy": "^1.18.0",