Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion apps/worker/src/boot-workers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,17 @@ export function bootWorkers() {
worker.on('completed', markEventsActivity);
worker.on('drained', markEventsActivity);

worker.run();
// Fail loud on startup — silent stuck shard otherwise.
// Runtime errors are handled by the shared workers.forEach listener below.
worker.run().catch((err) => {
logger.error(
{ shard: index, queueName, err },
'Worker startup failed — exiting',
);
// setTimeout+unref to let the logger flush before exit (matches the
// pattern used by uncaughtException/unhandledRejection handlers below).
setTimeout(() => process.exit(1), 1000).unref();
});
Comment on lines +170 to +180

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

process.exit(1) without delay risks losing the startup failure log.

The existing uncaughtException/unhandledRejection handlers in this same file (lines 406–414) use setTimeout(() => process.exit(1), 1000).unref() to give the logger time to flush before exiting. The new .catch() handler calls process.exit(1) immediately after logger.error(). If @openpanel/logger writes asynchronously, the log may never be flushed — leaving the failure silent, which is exactly what this PR aims to fix.

Additionally, setShuttingDown(true) is not called here, unlike every other exit path in the file (lines 399, 408, 413).

🔧 Proposed fix: follow existing exit pattern
     worker.run().catch((err) => {
       logger.error(
         { shard: index, queueName, err },
         'Worker startup failed — exiting',
       );
-      process.exit(1);
+      setShuttingDown(true);
+      setTimeout(() => process.exit(1), 1000).unref();
     });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Fail loud on startup — silent stuck shard otherwise.
worker.run().catch((err) => {
logger.error(
{ shard: index, queueName, err },
'Worker startup failed — exiting',
);
process.exit(1);
});
worker.run().catch((err) => {
logger.error(
{ shard: index, queueName, err },
'Worker startup failed — exiting',
);
setShuttingDown(true);
setTimeout(() => process.exit(1), 1000).unref();
});
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/worker/src/boot-workers.ts` around lines 173 - 180, The worker startup
failure path in boot-workers should follow the same shutdown pattern used by the
existing error handlers. In worker.run().catch(...) after logger.error, call
setShuttingDown(true) before exiting, and replace the immediate process.exit(1)
with a delayed exit via setTimeout(..., 1000).unref() so the startup failure log
can flush reliably. Use the existing shutdown/error symbols in this file
(worker.run, logger.error, setShuttingDown, process.exit) to align the .catch()
behavior with the uncaughtException and unhandledRejection handlers.

workers.push(worker);
logger.info({ concurrency }, `Started worker for ${queueName}`);
}
Expand Down