channel-worker 2.4.3 → 2.4.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.
@@ -1176,18 +1176,30 @@ class CommandPoller {
1176
1176
  const offlineRenderers = renderers.filter(r => !runningRenderers.includes(r));
1177
1177
 
1178
1178
  // 3. Crash recovery
1179
- // 3a. Offline profiles with assigned commands → reset + relaunch
1179
+ // 3a. Offline profiles with assigned commands → reset + relaunch.
1180
+ // BUT: Nstbrowser API can briefly drop a profile from its running list
1181
+ // during heavy ops (image gen, captcha solving). The reset endpoint
1182
+ // returns { skipped: 'heartbeat-fresh' } if the extension is still
1183
+ // sending heartbeats — meaning the profile is alive even though
1184
+ // Nstbrowser doesn't list it. Skip relaunch in that case to avoid
1185
+ // a tabs-close + tabs-open loop.
1180
1186
  for (const r of offlineRenderers) {
1181
1187
  try {
1182
1188
  const cmdCount = await this.api.rendererHasCommands(r.nst_profile_id);
1183
1189
  if (cmdCount > 0) {
1184
- console.log(`[scene-dispatch] Crash recovery: ${r.name} has ${cmdCount} commands but not running — relaunching`);
1190
+ console.log(`[scene-dispatch] Crash recovery: ${r.name} has ${cmdCount} commands but not running — checking heartbeat`);
1185
1191
  try {
1186
- await this.api.resetRendererCommands(r.nst_profile_id);
1192
+ const resetRes = await this.api.resetRendererCommands(r.nst_profile_id);
1193
+ if (resetRes && resetRes.skipped === 'heartbeat-fresh') {
1194
+ console.log(`[scene-dispatch] ${r.name} heartbeat fresh — extension is alive, skipping relaunch`);
1195
+ runningRenderers.push(r);
1196
+ this._profileLastActivity[r.nst_profile_id] = Date.now();
1197
+ continue;
1198
+ }
1187
1199
  await this._launchRendererProfile(r);
1188
1200
  runningRenderers.push(r);
1189
1201
  this._profileLastActivity[r.nst_profile_id] = Date.now();
1190
- console.log(`[scene-dispatch] ${r.name} recovered (${cmdCount} commands reset)`);
1202
+ console.log(`[scene-dispatch] ${r.name} recovered (${(resetRes && resetRes.modified) || cmdCount} commands reset)`);
1191
1203
  } catch (err) {
1192
1204
  console.error(`[scene-dispatch] Failed to recover ${r.name}: ${err.message}`);
1193
1205
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "channel-worker",
3
- "version": "2.4.3",
3
+ "version": "2.4.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": {