@camstack/addon-pipeline 1.1.29 → 1.1.30
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.
|
@@ -336,6 +336,51 @@ var PoolHandle = class {
|
|
|
336
336
|
}
|
|
337
337
|
async dispose() {}
|
|
338
338
|
};
|
|
339
|
+
/**
|
|
340
|
+
* How long to wait for a worker to exit on SIGTERM before escalating to
|
|
341
|
+
* SIGKILL. A worker idle between frames exits well under this; only a worker
|
|
342
|
+
* stuck in a native inference call (openvino/onnx C++) needs the escalation.
|
|
343
|
+
*/
|
|
344
|
+
var POOL_WORKER_TERM_GRACE_MS = 2e3;
|
|
345
|
+
/**
|
|
346
|
+
* Terminate a spawned child GRACEFULLY THEN FORCEFULLY: end stdin, send
|
|
347
|
+
* SIGTERM, and if the process hasn't exited within `graceMs`, send SIGKILL.
|
|
348
|
+
* Resolves once the process has exited (or was already dead).
|
|
349
|
+
*
|
|
350
|
+
* The old teardown sent SIGTERM and dropped the reference immediately — a
|
|
351
|
+
* worker busy in a native inference loop ignores SIGTERM and ORPHANS at full
|
|
352
|
+
* CPU (observed after an engine re-spin). SIGKILL cannot be ignored, so the
|
|
353
|
+
* escalation guarantees the process dies. Exported for tests.
|
|
354
|
+
*/
|
|
355
|
+
async function terminateChild(proc, graceMs) {
|
|
356
|
+
if (proc.exitCode !== null || proc.signalCode !== null) return;
|
|
357
|
+
try {
|
|
358
|
+
proc.stdin?.end();
|
|
359
|
+
} catch {}
|
|
360
|
+
await new Promise((resolve) => {
|
|
361
|
+
let settled = false;
|
|
362
|
+
let timer = null;
|
|
363
|
+
const done = () => {
|
|
364
|
+
if (settled) return;
|
|
365
|
+
settled = true;
|
|
366
|
+
if (timer) clearTimeout(timer);
|
|
367
|
+
resolve();
|
|
368
|
+
};
|
|
369
|
+
proc.once("exit", done);
|
|
370
|
+
try {
|
|
371
|
+
proc.kill("SIGTERM");
|
|
372
|
+
} catch {
|
|
373
|
+
done();
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
timer = setTimeout(() => {
|
|
377
|
+
try {
|
|
378
|
+
proc.kill("SIGKILL");
|
|
379
|
+
} catch {}
|
|
380
|
+
done();
|
|
381
|
+
}, graceMs);
|
|
382
|
+
});
|
|
383
|
+
}
|
|
339
384
|
var PoolWorker = class {
|
|
340
385
|
process = null;
|
|
341
386
|
receiveBuffer = Buffer.alloc(0);
|
|
@@ -491,12 +536,11 @@ var PoolWorker = class {
|
|
|
491
536
|
return await this.dispatch(MSG_COMMAND, payload);
|
|
492
537
|
}
|
|
493
538
|
async dispose() {
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
}
|
|
539
|
+
const proc = this.process;
|
|
540
|
+
if (!proc) return;
|
|
541
|
+
this.process = null;
|
|
542
|
+
this.ready = false;
|
|
543
|
+
await terminateChild(proc, POOL_WORKER_TERM_GRACE_MS);
|
|
500
544
|
}
|
|
501
545
|
dispatch(msgType, payload) {
|
|
502
546
|
const reqId = this.allocRequestId();
|
|
@@ -329,6 +329,51 @@ var PoolHandle = class {
|
|
|
329
329
|
}
|
|
330
330
|
async dispose() {}
|
|
331
331
|
};
|
|
332
|
+
/**
|
|
333
|
+
* How long to wait for a worker to exit on SIGTERM before escalating to
|
|
334
|
+
* SIGKILL. A worker idle between frames exits well under this; only a worker
|
|
335
|
+
* stuck in a native inference call (openvino/onnx C++) needs the escalation.
|
|
336
|
+
*/
|
|
337
|
+
var POOL_WORKER_TERM_GRACE_MS = 2e3;
|
|
338
|
+
/**
|
|
339
|
+
* Terminate a spawned child GRACEFULLY THEN FORCEFULLY: end stdin, send
|
|
340
|
+
* SIGTERM, and if the process hasn't exited within `graceMs`, send SIGKILL.
|
|
341
|
+
* Resolves once the process has exited (or was already dead).
|
|
342
|
+
*
|
|
343
|
+
* The old teardown sent SIGTERM and dropped the reference immediately — a
|
|
344
|
+
* worker busy in a native inference loop ignores SIGTERM and ORPHANS at full
|
|
345
|
+
* CPU (observed after an engine re-spin). SIGKILL cannot be ignored, so the
|
|
346
|
+
* escalation guarantees the process dies. Exported for tests.
|
|
347
|
+
*/
|
|
348
|
+
async function terminateChild(proc, graceMs) {
|
|
349
|
+
if (proc.exitCode !== null || proc.signalCode !== null) return;
|
|
350
|
+
try {
|
|
351
|
+
proc.stdin?.end();
|
|
352
|
+
} catch {}
|
|
353
|
+
await new Promise((resolve) => {
|
|
354
|
+
let settled = false;
|
|
355
|
+
let timer = null;
|
|
356
|
+
const done = () => {
|
|
357
|
+
if (settled) return;
|
|
358
|
+
settled = true;
|
|
359
|
+
if (timer) clearTimeout(timer);
|
|
360
|
+
resolve();
|
|
361
|
+
};
|
|
362
|
+
proc.once("exit", done);
|
|
363
|
+
try {
|
|
364
|
+
proc.kill("SIGTERM");
|
|
365
|
+
} catch {
|
|
366
|
+
done();
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
timer = setTimeout(() => {
|
|
370
|
+
try {
|
|
371
|
+
proc.kill("SIGKILL");
|
|
372
|
+
} catch {}
|
|
373
|
+
done();
|
|
374
|
+
}, graceMs);
|
|
375
|
+
});
|
|
376
|
+
}
|
|
332
377
|
var PoolWorker = class {
|
|
333
378
|
process = null;
|
|
334
379
|
receiveBuffer = Buffer.alloc(0);
|
|
@@ -484,12 +529,11 @@ var PoolWorker = class {
|
|
|
484
529
|
return await this.dispatch(MSG_COMMAND, payload);
|
|
485
530
|
}
|
|
486
531
|
async dispose() {
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
}
|
|
532
|
+
const proc = this.process;
|
|
533
|
+
if (!proc) return;
|
|
534
|
+
this.process = null;
|
|
535
|
+
this.ready = false;
|
|
536
|
+
await terminateChild(proc, POOL_WORKER_TERM_GRACE_MS);
|
|
493
537
|
}
|
|
494
538
|
dispatch(msgType, payload) {
|
|
495
539
|
const reqId = this.allocRequestId();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/addon-pipeline",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.30",
|
|
4
4
|
"description": "CamStack Pipeline bundle — runner, detection, motion, decoders, audio + stream broker. Multi-entry npm package shipping 7 addons under a single bundle.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"camstack",
|