@danhachuel/thunderbolt 0.5.73 → 0.5.75
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.
- package/package.json +1 -1
- package/scripts/cli.mjs +75 -8
package/package.json
CHANGED
package/scripts/cli.mjs
CHANGED
|
@@ -276,14 +276,77 @@ proxy.on("error", (error) => {
|
|
|
276
276
|
proxy.listen(publicPort, "127.0.0.1", () => {
|
|
277
277
|
console.log(`Thunderbolt: interface disponível em http://localhost:${publicPort}/`);
|
|
278
278
|
});
|
|
279
|
-
//
|
|
280
|
-
//
|
|
281
|
-
//
|
|
282
|
-
|
|
283
|
-
|
|
279
|
+
// Os workers são geridos pelo launcher para que um clique em Start na UI
|
|
280
|
+
// também active o processamento, mesmo sem automação de canal configurada.
|
|
281
|
+
// Cada worker só existe enquanto a respectiva fila tiver trabalho pendente.
|
|
282
|
+
let worker = null;
|
|
283
|
+
let pipelineWorker = null;
|
|
284
284
|
const restartExitCode = 75;
|
|
285
285
|
let shuttingDown = false;
|
|
286
286
|
let child;
|
|
287
|
+
let workerRestartTimer = null;
|
|
288
|
+
let pipelineRestartTimer = null;
|
|
289
|
+
let workerMonitorTimer = null;
|
|
290
|
+
|
|
291
|
+
function startAutomationWorker() {
|
|
292
|
+
if (shuttingDown || worker || !hasScheduledAutomation()) return;
|
|
293
|
+
worker = spawn(python, ["-m", "hermes_ui.automation_worker"], {
|
|
294
|
+
cwd: root,
|
|
295
|
+
stdio: "inherit",
|
|
296
|
+
env: runtimeEnv,
|
|
297
|
+
windowsHide: false,
|
|
298
|
+
});
|
|
299
|
+
worker.on("error", (error) => console.error(`Thunderbolt worker: ${error.message}`));
|
|
300
|
+
worker.on("exit", (code, signal) => {
|
|
301
|
+
worker = null;
|
|
302
|
+
if (shuttingDown) return;
|
|
303
|
+
console.error(`Thunderbolt worker: terminou (código ${code ?? "-"}, sinal ${signal ?? "-"}).`);
|
|
304
|
+
if (hasScheduledAutomation()) {
|
|
305
|
+
workerRestartTimer = setTimeout(() => {
|
|
306
|
+
workerRestartTimer = null;
|
|
307
|
+
startAutomationWorker();
|
|
308
|
+
}, 5000);
|
|
309
|
+
}
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
function stopPipelineWorker() {
|
|
314
|
+
if (pipelineRestartTimer) {
|
|
315
|
+
clearTimeout(pipelineRestartTimer);
|
|
316
|
+
pipelineRestartTimer = null;
|
|
317
|
+
}
|
|
318
|
+
if (pipelineWorker && !pipelineWorker.killed) pipelineWorker.kill();
|
|
319
|
+
pipelineWorker = null;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
function startPipelineWorker() {
|
|
323
|
+
if (shuttingDown || pipelineWorker || !hasPendingPipelineWork()) return;
|
|
324
|
+
pipelineWorker = spawn(python, ["-m", "hermes_ui.pipeline_worker"], {
|
|
325
|
+
cwd: root,
|
|
326
|
+
stdio: "inherit",
|
|
327
|
+
env: runtimeEnv,
|
|
328
|
+
windowsHide: false,
|
|
329
|
+
});
|
|
330
|
+
pipelineWorker.on("error", (error) => console.error(`Thunderbolt pipeline worker: ${error.message}`));
|
|
331
|
+
pipelineWorker.on("exit", (code, signal) => {
|
|
332
|
+
pipelineWorker = null;
|
|
333
|
+
if (shuttingDown) return;
|
|
334
|
+
console.error(`Thunderbolt pipeline worker: terminou (código ${code ?? "-"}, sinal ${signal ?? "-"}).`);
|
|
335
|
+
if (hasPendingPipelineWork()) {
|
|
336
|
+
pipelineRestartTimer = setTimeout(() => {
|
|
337
|
+
pipelineRestartTimer = null;
|
|
338
|
+
startPipelineWorker();
|
|
339
|
+
}, 5000);
|
|
340
|
+
}
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
function monitorWorkers() {
|
|
345
|
+
if (shuttingDown) return;
|
|
346
|
+
if (hasPendingPipelineWork()) startPipelineWorker();
|
|
347
|
+
else if (pipelineWorker) stopPipelineWorker();
|
|
348
|
+
startAutomationWorker();
|
|
349
|
+
}
|
|
287
350
|
|
|
288
351
|
function startStreamlit() {
|
|
289
352
|
child = spawn(python, [streamlitBootstrap, "run", main, "--server.port", String(backendPort), "--server.address", "127.0.0.1"], {
|
|
@@ -323,10 +386,14 @@ startStreamlit();
|
|
|
323
386
|
const stopWorker = () => {
|
|
324
387
|
shuttingDown = true;
|
|
325
388
|
proxy.close();
|
|
389
|
+
if (workerRestartTimer) clearTimeout(workerRestartTimer);
|
|
390
|
+
if (workerMonitorTimer) clearInterval(workerMonitorTimer);
|
|
326
391
|
if (worker && !worker.killed) worker.kill();
|
|
327
|
-
|
|
392
|
+
stopPipelineWorker();
|
|
328
393
|
};
|
|
329
394
|
process.on("SIGINT", stopWorker);
|
|
330
395
|
process.on("SIGTERM", stopWorker);
|
|
331
|
-
|
|
332
|
-
|
|
396
|
+
monitorWorkers();
|
|
397
|
+
// O launcher verifica apenas os JSONs locais; não existe timer no Streamlit
|
|
398
|
+
// nem worker persistente quando não há tarefa pendente.
|
|
399
|
+
workerMonitorTimer = setInterval(monitorWorkers, 2000);
|