Skip to content

follow bullmq docs for connection#57

Merged
aidanhibbard merged 2 commits into
mainfrom
follow-bullmq-connection-docs
May 31, 2026
Merged

follow bullmq docs for connection#57
aidanhibbard merged 2 commits into
mainfrom
follow-bullmq-connection-docs

Conversation

@aidanhibbard

Copy link
Copy Markdown
Owner

Summary

Briefly describe what this PR does and why.

Changes

  • Connection handling

How to Test

  1. verify startup and shutdown happens per spec

Screenshots (optional)

If applicable, add screenshots or recordings.

Linked Issues

Closes #

Checklist

  • I read CONTRIBUTING.md and agree to the Code of Conduct
  • I tested these changes locally
  • Added/updated tests if needed
  • Updated docs (README/docs) if needed
  • npm run ci passes (or npm run lint and npm test at minimum)
  • No breaking changes, or I documented them above

@aidanhibbard aidanhibbard self-assigned this May 31, 2026
@aidanhibbard aidanhibbard added the bug Something isn't working label May 31, 2026
@coderabbitai

coderabbitai Bot commented May 31, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@aidanhibbard, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 42 minutes and 54 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 85c2b8f3-794e-4087-83bd-b2e863abbdd8

📥 Commits

Reviewing files that changed from the base of the PR and between 8111b95 and d043eab.

📒 Files selected for processing (1)
  • src/runtime/server/plugins/close-processor.ts
📝 Walkthrough

Walkthrough

This PR adds graceful shutdown handling to the Nuxt processor module. The stopAll() API is refactored to accept options and return detailed results. A new Nitro server plugin (close-processor) registers a shutdown hook that calls stopAll(). Queues are configured with enableOfflineQueue: false, and both queues and workers attach error event handlers. A new utility generates worker process shutdown handlers with configurable timeout and force-stop fallback.

Changes

Worker Shutdown Integration

Layer / File(s) Summary
Shutdown API contract and core runtime implementation
src/runtime/server/utils/workers.ts, src/runtime/server/utils/index.ts
StopAllOptions { force?: boolean } and StopAllResult { ok, errors } types added; queue connections set enableOfflineQueue: false; error event handlers registered on Queue and Worker instances; stopAll() changed from no-arg Promise to options-accepting function returning { ok: boolean, errors: Error[] } with error aggregation via Promise.allSettled.
Nitro server plugin and module wiring
src/runtime/server/plugins/close-processor.ts, src/module.ts
New close-processor plugin registers Nitro close hook to invoke useProcessor().stopAll() on server shutdown and log failures; module imports updated to register plugin via addServerPlugin.
Worker process shutdown handler generation
src/utils/generate-workers-index-wrapper.ts, src/utils/generate-workers-entry-content.ts, src/module.ts
New generateWorkersIndexWrapper utility produces wrapper script with graceful shutdown: exports DEFAULT_SHUTDOWN_TIMEOUT_MS, registers SIGINT/SIGTERM/SIGQUIT handlers, races app.stop() against timeout via Promise.race, falls back to force-stop on timeout, exits with appropriate code. Generated createWorkersApp().stop() updated to accept and forward options to api.stopAll(opts).
API documentation and changelog updates
docs/api.md, docs/redis.md, changelog.md
useProcessor().stopAll() example and signature updated to show options/results; new StopAllOptions and StopAllResult types documented; createWorkersApp().stop() signature updated; new "Connection behavior (BullMQ)" section documents enableOfflineQueue: false and error logging; changelog records enhancements, docs, and test updates.
Comprehensive test coverage
spec/runtime/handlers/defineQueue.spec.ts, spec/runtime/handlers/defineWorker.spec.ts, spec/runtime/plugins/close-processor.spec.ts, spec/runtime/utils/workers.spec.ts, spec/utils/generate-workers-entry-content.spec.ts, spec/utils/generate-workers-index-wrapper.spec.ts
Handler tests extend mocking (consola, bullmq) and convert beforeEach to async with cleanup; close-processor suite verifies hook registration and error logging; workers.spec extends to assert enableOfflineQueue: false across all connection scenarios, error handler attachment, stopAll error aggregation and logging, and force-stop option forwarding; entry content and new wrapper tests validate generated code signatures and shutdown behaviors.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • aidanhibbard/nuxt-processor#53: Modifies queue/worker connection setup in src/runtime/server/utils/workers.ts (normalizes Redis options and enforces maxRetriesPerRequest: null), overlapping with this PR's connection layer changes.
  • aidanhibbard/nuxt-processor#44: Alters workers entry generation logic in generate-workers-entry-content to handle --workers selection and stop behavior, related to this PR's changes to generated stop function signatures.

Suggested labels

enhancement, documentation

Poem

🐰 Signals caught with grace so fine,
Timeouts queued in a shutdown line,
Errors logged, no queue left behind,
Graceful close for peace of mind,
Workers rest when servers say goodbye! ✨

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive The description is incomplete. While the template structure is present, the 'Summary' section lacks detail, 'Changes' section is minimal ('Connection handling' without elaboration), and the test instructions are vague. Expand the Summary to explain what specific connection handling changes were made and why. Provide more detailed test steps and clarify the scope of 'Connection handling' changes.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'follow bullmq docs for connection' is specific and directly related to the PR's main objective of adjusting connection handling per BullMQ documentation.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch follow-bullmq-connection-docs

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
src/utils/generate-workers-index-wrapper.ts (1)

14-14: ⚡ Quick win

Forced stop has no timeout — a hung app.stop({ force: true }) blocks exit indefinitely.

The graceful timeout fires correctly, but the fallback await app.stop({ force: true }) is itself unbounded. Since process.exit is only scheduled in the finally block, it never runs if the forced stop hangs, defeating the purpose of the shutdown deadline. Consider an independent hard-exit safety timer that fires regardless of where the stop logic is stuck.

♻️ Sketch: independent hard-exit safety net
- + `const shutdown = async (signal) => { if (shuttingDown) return; shuttingDown = true; let exitCode = 0; try { logger.info(...
+ + `const shutdown = async (signal) => { if (shuttingDown) return; shuttingDown = true; let exitCode = 0; const hardExit = setTimeout(() => process.exit(1), SHUTDOWN_TIMEOUT_MS * 2); if (typeof hardExit.unref === 'function') hardExit.unref(); try { logger.info(...

(Clear hardExit in the finally before scheduling the normal exit.)

Also note the Promise.race timeout timer is never cleared and the original app.stop() promise is left orphaned after a timeout, which can surface as an unhandled rejection.

🤖 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 `@src/utils/generate-workers-index-wrapper.ts` at line 14, The shutdown handler
(shutdown) currently leaves the forced app.stop({ force: true }) unbounded and
never clears the Promise.race timeout, so add an independent hard-exit safety
timer (e.g., HARD_EXIT_TIMEOUT_MS) started at shutdown start that will call
process.exit(1) if any part of shutdown hangs; wrap the forced stop call inside
a Promise.race with a short timeout and clear that timeout when stop resolves to
avoid orphaned timers, also clear the initial graceful timeout timer created for
Promise.race([app.stop(), timeout]) so the original app.stop() promise isn't
orphaned, and finally ensure you clear the hard-exit timer in the finally block
before scheduling the normal process.exit(exitCode); refer to shutdown,
app.stop, SHUTDOWN_TIMEOUT_MS and the new hard-exit timer symbol when making
these changes.
🤖 Prompt for all review comments with 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.

Nitpick comments:
In `@src/utils/generate-workers-index-wrapper.ts`:
- Line 14: The shutdown handler (shutdown) currently leaves the forced
app.stop({ force: true }) unbounded and never clears the Promise.race timeout,
so add an independent hard-exit safety timer (e.g., HARD_EXIT_TIMEOUT_MS)
started at shutdown start that will call process.exit(1) if any part of shutdown
hangs; wrap the forced stop call inside a Promise.race with a short timeout and
clear that timeout when stop resolves to avoid orphaned timers, also clear the
initial graceful timeout timer created for Promise.race([app.stop(), timeout])
so the original app.stop() promise isn't orphaned, and finally ensure you clear
the hard-exit timer in the finally block before scheduling the normal
process.exit(exitCode); refer to shutdown, app.stop, SHUTDOWN_TIMEOUT_MS and the
new hard-exit timer symbol when making these changes.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4b839170-bb7a-4b22-9181-f3a6d23bef53

📥 Commits

Reviewing files that changed from the base of the PR and between 7b4bc83 and 8111b95.

⛔ Files ignored due to path filters (2)
  • package-lock.json is excluded by !**/package-lock.json
  • spec/utils/__snapshots__/generate-workers-entry-content.spec.ts.snap is excluded by !**/*.snap
📒 Files selected for processing (16)
  • .cursor/mcp.json
  • changelog.md
  • docs/api.md
  • docs/redis.md
  • spec/runtime/handlers/defineQueue.spec.ts
  • spec/runtime/handlers/defineWorker.spec.ts
  • spec/runtime/plugins/close-processor.spec.ts
  • spec/runtime/utils/workers.spec.ts
  • spec/utils/generate-workers-entry-content.spec.ts
  • spec/utils/generate-workers-index-wrapper.spec.ts
  • src/module.ts
  • src/runtime/server/plugins/close-processor.ts
  • src/runtime/server/utils/index.ts
  • src/runtime/server/utils/workers.ts
  • src/utils/generate-workers-entry-content.ts
  • src/utils/generate-workers-index-wrapper.ts

@aidanhibbard aidanhibbard merged commit da51072 into main May 31, 2026
3 checks passed
@aidanhibbard aidanhibbard deleted the follow-bullmq-connection-docs branch May 31, 2026 22:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant