channel-worker 2.2.2 → 2.2.4

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.
@@ -1214,9 +1214,17 @@ class CommandPoller {
1214
1214
  const stillOffline = renderers.filter(r => !runningRenderers.includes(r));
1215
1215
  console.log(`[scene-dispatch] running=${runningRenderers.length}/${parallelLimit} offline=${stillOffline.length} queue=${queueCount} names=[${runningRenderers.map(r=>r.name)}]`);
1216
1216
 
1217
- // Only launch if queue has more work than running profiles can handle
1218
- const freeSlots = Math.max(0, queueCount - runningRenderers.length);
1219
- const neededLaunches = Math.min(parallelLimit - runningRenderers.length, stillOffline.length, freeSlots);
1217
+ // Count how many running profiles are actually free (no commands)
1218
+ let freeRunning = 0;
1219
+ for (const r of runningRenderers) {
1220
+ try {
1221
+ const c = await this.api.rendererHasCommands(r.nst_profile_id);
1222
+ if (c === 0) freeRunning++;
1223
+ } catch {}
1224
+ }
1225
+ // Only launch new profiles if queue has more work than free profiles
1226
+ const needNew = Math.max(0, queueCount - freeRunning);
1227
+ const neededLaunches = Math.min(parallelLimit - runningRenderers.length, stillOffline.length, needNew);
1220
1228
  for (let li = 0; li < neededLaunches; li++) {
1221
1229
  const toLaunch = stillOffline[li];
1222
1230
  console.log(`[scene-dispatch] Launching ${toLaunch.name} (running: ${runningRenderers.length + li}/${parallelLimit})`);
@@ -1310,12 +1318,18 @@ class CommandPoller {
1310
1318
 
1311
1319
  for (const browser of running) {
1312
1320
  const profileId = browser.profileId;
1313
- const lastActivity = this._profileLastActivity[profileId] || 0;
1314
- if (lastActivity && (now - lastActivity) > IDLE_TIMEOUT) {
1321
+ const name = browser.name?.toLowerCase();
1322
+ // Match by UUID or name (renderers use name as nst_profile_id)
1323
+ const lastActivity = this._profileLastActivity[profileId]
1324
+ || (name && this._profileLastActivity[name])
1325
+ || 0;
1326
+ if (!lastActivity) continue; // never tracked — skip (just launched by another process)
1327
+ if ((now - lastActivity) > IDLE_TIMEOUT) {
1315
1328
  console.log(`[profile-timeout] Closing idle profile ${browser.name || profileId} (idle ${Math.round((now - lastActivity) / 1000)}s)`);
1316
1329
  try {
1317
1330
  await this.nst.stopProfile(profileId);
1318
1331
  delete this._profileLastActivity[profileId];
1332
+ if (name) delete this._profileLastActivity[name];
1319
1333
  } catch (e) {
1320
1334
  console.warn(`[profile-timeout] Failed to close ${profileId}: ${e.message}`);
1321
1335
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "channel-worker",
3
- "version": "2.2.2",
3
+ "version": "2.2.4",
4
4
  "description": "Channel Manager worker daemon — runs on remote machines to execute video pipeline jobs",
5
5
  "main": "lib/daemon.js",
6
6
  "bin": {