@camstack/system 1.1.12 → 1.1.14

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.
@@ -1,4 +1,4 @@
1
- import { InferProvider, deviceManagerCapability, AddonContext } from '@camstack/types';
1
+ import { AddonContext, deviceManagerCapability, InferProvider } from '@camstack/types';
2
2
  import { DeviceManagerSettings, DeviceMetaStore } from './device-meta-store.js';
3
3
  import { ProviderContext } from './device-provider-context.js';
4
4
  type IDeviceManagerProvider = InferProvider<typeof deviceManagerCapability>;
package/dist/index.js CHANGED
@@ -92343,6 +92343,60 @@ async function getPidStats$1(pids) {
92343
92343
  });
92344
92344
  });
92345
92345
  }
92346
+ /**
92347
+ * Heavy runners (media / ML / native): frame data lives in shared memory (`@camstack/shm-ring`) and
92348
+ * native buffers, but these processes still allocate enough on the JS heap that shrinking V8's
92349
+ * young generation would add scavenge-GC churn, and a low old-space cap would risk OOM. They keep
92350
+ * V8 defaults. Everyone else is a lightweight, mostly-idle control-plane runner (providers, auth,
92351
+ * tunnels, storage, smtp, notifier, admin-ui) that over-reserves ~15 MB of young-gen it never uses.
92352
+ *
92353
+ * Matched by a substring of the addon package dir (e.g. `.../@camstack/addon-pipeline/dist`), so it
92354
+ * is robust to the addonId vs package-name distinction.
92355
+ */
92356
+ var HEAVY_RUNNER_DIR_MARKERS = [
92357
+ "addon-pipeline",
92358
+ "addon-detection-pipeline",
92359
+ "addon-pipeline-runner",
92360
+ "addon-pipeline-orchestrator",
92361
+ "addon-decoder",
92362
+ "addon-benchmark",
92363
+ "addon-audio-codec",
92364
+ "addon-motion",
92365
+ "addon-embedding",
92366
+ "addon-model-studio",
92367
+ "addon-analytics-suite",
92368
+ "addon-provider-reolink",
92369
+ "addon-provider-matter"
92370
+ ];
92371
+ function isHeavyRunner(addons) {
92372
+ return addons.some((a) => HEAVY_RUNNER_DIR_MARKERS.some((m) => a.addonDir.includes(m)));
92373
+ }
92374
+ /**
92375
+ * Per-placement V8 heap flags (Block D). LIGHT runners cap their young generation
92376
+ * (`--max-semi-space-size`) to reclaim V8's over-reservation — a measured ~15 MB/runner win.
92377
+ * HEAVY runners keep V8 defaults. The old-space cap is opt-in via env (unset = uncapped = no OOM
92378
+ * risk) so it can be enabled after before/after measurement on the real cluster.
92379
+ *
92380
+ * Kill-switch: `CAMSTACK_RUNNER_HEAP_TUNING=off` disables all flags (recover without a rebuild).
92381
+ * Overrides: `CAMSTACK_RUNNER_LIGHT_SEMI_SPACE_MB` (default 2), `CAMSTACK_RUNNER_LIGHT_MAX_OLD_MB`
92382
+ * (default unset = no old-space cap).
92383
+ */
92384
+ function runnerHeapFlags(addons) {
92385
+ if (process.env["CAMSTACK_RUNNER_HEAP_TUNING"] === "off") return [];
92386
+ if (isHeavyRunner(addons)) return [];
92387
+ const semiMb = positiveIntEnv("CAMSTACK_RUNNER_LIGHT_SEMI_SPACE_MB", 2);
92388
+ const oldMb = positiveIntEnv("CAMSTACK_RUNNER_LIGHT_MAX_OLD_MB", 0);
92389
+ const flags = [];
92390
+ if (semiMb > 0) flags.push(`--max-semi-space-size=${semiMb}`);
92391
+ if (oldMb > 0) flags.push(`--max-old-space-size=${oldMb}`);
92392
+ return flags;
92393
+ }
92394
+ function positiveIntEnv(name, fallback) {
92395
+ const raw = process.env[name];
92396
+ if (raw === void 0) return fallback;
92397
+ const n = Number.parseInt(raw, 10);
92398
+ return Number.isFinite(n) && n >= 0 ? n : fallback;
92399
+ }
92346
92400
  var MAX_BACKOFF_MS = 3e4;
92347
92401
  var CRASH_WINDOW_MS = 6e4;
92348
92402
  var MAX_CRASHES_IN_WINDOW = 5;
@@ -92421,7 +92475,8 @@ function createProcessService(parentNodeId, dataDir, deps, parentTcpPort, parent
92421
92475
  ...parentUdsPath !== void 0 ? { CAMSTACK_PARENT_UDS_PATH: parentUdsPath } : {},
92422
92476
  ...env
92423
92477
  };
92424
- const child = spawnFn(process.execPath, [runnerPath], {
92478
+ const heapFlags = runnerHeapFlags(addons);
92479
+ const child = spawnFn(process.execPath, [...heapFlags, runnerPath], {
92425
92480
  env: childEnv,
92426
92481
  stdio: [
92427
92482
  "ignore",
package/dist/index.mjs CHANGED
@@ -92335,6 +92335,60 @@ async function getPidStats$1(pids) {
92335
92335
  });
92336
92336
  });
92337
92337
  }
92338
+ /**
92339
+ * Heavy runners (media / ML / native): frame data lives in shared memory (`@camstack/shm-ring`) and
92340
+ * native buffers, but these processes still allocate enough on the JS heap that shrinking V8's
92341
+ * young generation would add scavenge-GC churn, and a low old-space cap would risk OOM. They keep
92342
+ * V8 defaults. Everyone else is a lightweight, mostly-idle control-plane runner (providers, auth,
92343
+ * tunnels, storage, smtp, notifier, admin-ui) that over-reserves ~15 MB of young-gen it never uses.
92344
+ *
92345
+ * Matched by a substring of the addon package dir (e.g. `.../@camstack/addon-pipeline/dist`), so it
92346
+ * is robust to the addonId vs package-name distinction.
92347
+ */
92348
+ var HEAVY_RUNNER_DIR_MARKERS = [
92349
+ "addon-pipeline",
92350
+ "addon-detection-pipeline",
92351
+ "addon-pipeline-runner",
92352
+ "addon-pipeline-orchestrator",
92353
+ "addon-decoder",
92354
+ "addon-benchmark",
92355
+ "addon-audio-codec",
92356
+ "addon-motion",
92357
+ "addon-embedding",
92358
+ "addon-model-studio",
92359
+ "addon-analytics-suite",
92360
+ "addon-provider-reolink",
92361
+ "addon-provider-matter"
92362
+ ];
92363
+ function isHeavyRunner(addons) {
92364
+ return addons.some((a) => HEAVY_RUNNER_DIR_MARKERS.some((m) => a.addonDir.includes(m)));
92365
+ }
92366
+ /**
92367
+ * Per-placement V8 heap flags (Block D). LIGHT runners cap their young generation
92368
+ * (`--max-semi-space-size`) to reclaim V8's over-reservation — a measured ~15 MB/runner win.
92369
+ * HEAVY runners keep V8 defaults. The old-space cap is opt-in via env (unset = uncapped = no OOM
92370
+ * risk) so it can be enabled after before/after measurement on the real cluster.
92371
+ *
92372
+ * Kill-switch: `CAMSTACK_RUNNER_HEAP_TUNING=off` disables all flags (recover without a rebuild).
92373
+ * Overrides: `CAMSTACK_RUNNER_LIGHT_SEMI_SPACE_MB` (default 2), `CAMSTACK_RUNNER_LIGHT_MAX_OLD_MB`
92374
+ * (default unset = no old-space cap).
92375
+ */
92376
+ function runnerHeapFlags(addons) {
92377
+ if (process.env["CAMSTACK_RUNNER_HEAP_TUNING"] === "off") return [];
92378
+ if (isHeavyRunner(addons)) return [];
92379
+ const semiMb = positiveIntEnv("CAMSTACK_RUNNER_LIGHT_SEMI_SPACE_MB", 2);
92380
+ const oldMb = positiveIntEnv("CAMSTACK_RUNNER_LIGHT_MAX_OLD_MB", 0);
92381
+ const flags = [];
92382
+ if (semiMb > 0) flags.push(`--max-semi-space-size=${semiMb}`);
92383
+ if (oldMb > 0) flags.push(`--max-old-space-size=${oldMb}`);
92384
+ return flags;
92385
+ }
92386
+ function positiveIntEnv(name, fallback) {
92387
+ const raw = process.env[name];
92388
+ if (raw === void 0) return fallback;
92389
+ const n = Number.parseInt(raw, 10);
92390
+ return Number.isFinite(n) && n >= 0 ? n : fallback;
92391
+ }
92338
92392
  var MAX_BACKOFF_MS = 3e4;
92339
92393
  var CRASH_WINDOW_MS = 6e4;
92340
92394
  var MAX_CRASHES_IN_WINDOW = 5;
@@ -92413,7 +92467,8 @@ function createProcessService(parentNodeId, dataDir, deps, parentTcpPort, parent
92413
92467
  ...parentUdsPath !== void 0 ? { CAMSTACK_PARENT_UDS_PATH: parentUdsPath } : {},
92414
92468
  ...env
92415
92469
  };
92416
- const child = spawnFn(process.execPath, [runnerPath], {
92470
+ const heapFlags = runnerHeapFlags(addons);
92471
+ const child = spawnFn(process.execPath, [...heapFlags, runnerPath], {
92417
92472
  env: childEnv,
92418
92473
  stdio: [
92419
92474
  "ignore",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/system",
3
- "version": "1.1.12",
3
+ "version": "1.1.14",
4
4
  "description": "Core addon for CamStack — builtins, pipeline, process management, auth, logging, events",
5
5
  "keywords": [
6
6
  "camstack",