[grade=pending] fix: eliminate CPU waste from duplicate workflows, self-updater crash loop, and aggressive polling
CI / Test & Lint (push) Canceled after 0s
CI / Security audit (push) Canceled after 0s

- Remove duplicate WorkflowEngine instantiation (was created in both app.js
  and server.js, causing every periodic workflow to fire twice)
- Fix self-updater _isNewer() crash loop: same-version different-commit was
  treated as 'update available', then crashed on undefined tarball path.
  Now only triggers on actual version bumps
- Increase container stats interval from 10s to 30s
- Increase health check interval from 30s to 60s
- Add disk cleanup debounce (skip if last cleanup < 30 min ago)
- Remove redundant disk-space-monitor from server.js (already in app.js)
- 69/69 tests pass
This commit is contained in:
Hermes
2026-08-13 10:57:20 -07:00
parent 9d085ebf94
commit 234df5038c
7 changed files with 48 additions and 21 deletions
+9 -7
View File
@@ -21,7 +21,7 @@ process.on('uncaughtException', (error) => {
(async () => {
try {
// Create and configure Express app
const { app, log, config, licenseManager } = await createApp();
const { app, log, config, licenseManager, workflowEngine: appWorkflowEngine } = await createApp();
// Load license
await licenseManager.load();
@@ -112,11 +112,13 @@ process.on('uncaughtException', (error) => {
try { logDigest = require('./src/security/log-digest'); } catch { /* optional */ }
try { bundledWorkflows = require('./src/recipes/bundled-workflows'); } catch { /* optional */ }
// Initialize workflow engine if bundled-workflows is available
// NOTE: createApp() already initializes the workflow engine in src/app.js
// This block is kept for backward compat with entry points that don't use createApp()
let workflowEngine = null;
if (bundledWorkflows) {
// Reuse the workflow engine created by createApp() to avoid duplicate
// scheduled jobs (DC-CPU: two WorkflowEngine instances each scheduled
// health-check-on-interval, causing every periodic workflow to fire
// twice and double the polling load). Only create one if createApp()
// didn't (e.g. legacy entry points without docker).
let workflowEngine = appWorkflowEngine || null;
if (!workflowEngine && bundledWorkflows) {
try {
const { fetchT } = require('./src/utils/http');
const { WorkflowEngine } = bundledWorkflows;
@@ -134,7 +136,7 @@ process.on('uncaughtException', (error) => {
servicesStateManager
};
workflowEngine = new WorkflowEngine(workflowCtx);
log.info('server', 'Workflow engine initialized');
log.info('server', 'Workflow engine initialized (fallback)');
} catch (err) {
log.error('server', 'Workflow engine failed to initialize', { error: err.message });
}