Skip to content

fix(rivetkit): restore waitForNames and fix queue type errors#4116

Closed
NathanFlurry wants to merge 1 commit intomainfrom
02-04-fix_rivetkit_restore_waitfornames_and_fix_queue_type_errors
Closed

fix(rivetkit): restore waitForNames and fix queue type errors#4116
NathanFlurry wants to merge 1 commit intomainfrom
02-04-fix_rivetkit_restore_waitfornames_and_fix_queue_type_errors

Conversation

@NathanFlurry
Copy link
Member

Description

Please include a summary of the changes and the related issue. Please also include relevant motivation and context.

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How Has This Been Tested?

Please describe the tests that you ran to verify your changes.

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

@railway-app railway-app bot temporarily deployed to rivet-frontend / rivet-pr-4116 February 4, 2026 21:37 Destroyed
@railway-app
Copy link

railway-app bot commented Feb 4, 2026

🚅 Deployed to the rivet-pr-4116 environment in rivet-frontend

Service Status Web Updated (UTC)
frontend-inspector ❌ Build Failed (View Logs) Web Feb 4, 2026 at 10:12 pm
frontend-cloud ❌ Build Failed (View Logs) Web Feb 4, 2026 at 10:12 pm
website ❌ Build Failed (View Logs) Web Feb 4, 2026 at 10:00 pm
mcp-hub ✅ Success (View Logs) Web Feb 4, 2026 at 9:38 pm

Copy link
Member Author

NathanFlurry commented Feb 4, 2026


How to use the Graphite Merge Queue

Add the label merge-queue to this PR to add it to the merge queue.

You must have a Graphite account in order to use the merge queue. Sign up using this link.

An organization admin has enabled the Graphite Merge Queue in this repository.

Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue.

This stack of pull requests is managed by Graphite. Learn more about stacking.

@claude
Copy link

claude bot commented Feb 4, 2026

PR Review: fix(rivetkit): restore waitForNames and fix queue type errors

Summary

This PR restores the waitForNames functionality to the queue manager and fixes a type error in the queue's send method. Overall, the implementation is solid and follows good patterns for async event handling.


✅ Strengths

  1. Proper cleanup handling: The waitForNames implementation correctly handles cleanup for both actor abort signals and custom abort signals, preventing memory leaks.

  2. Race condition handling: The method checks for existing messages before setting up listeners, avoiding race conditions where messages arrive between the check and listener setup.

  3. Type safety fix: The send method now properly returns a QueueMessage by converting the internal message format, fixing the type mismatch.

  4. Good separation of concerns: The MessageListener interface is well-defined and the notification logic is cleanly separated.


🔍 Code Quality & Best Practices

queue-manager.ts:366-415

The waitForNames implementation is well-structured, but there are a few considerations:

  1. Early return timing: Lines 393-395 call onActorAbort() which calls listener.reject(), which calls this.#removeMessageListener(listener). However, the listener hasn't been added to this.#messageListeners yet (that happens on line 412), so the removal is a no-op. While this works, it's slightly confusing. Consider either:

    • Returning directly with reject(new errors.ActorAborted()) without going through the listener methods
    • Adding a comment explaining why the listener cleanup is called before the listener is registered
  2. Duplicate abort handling: Lines 402-409 have identical logic to lines 390-399 (just for a different signal). This duplication could be reduced, though it's not critical given the small scope.

queue-manager.ts:540-557

The notification logic looks good. Spreading the set ([...this.#messageListeners]) is important to avoid issues if listeners are removed during iteration.

queue.ts:101-104

Good fix. The method now properly converts the internal queue message format to the public QueueMessage interface.


🐛 Potential Issues

  1. Missing public API exposure: The waitForNames method is added to QueueManager but I don't see it being exposed through the public ActorQueue class. This means it's only accessible internally (e.g., by the workflow driver at driver.ts:204). If this is intentional for internal-only use, consider adding a comment or JSDoc indicating this. If users should access it, it needs to be exposed through ActorQueue.

  2. Test coverage: The driver test at actor-queue.ts:155 was modified to add optional chaining (result?.status), but there's no new test coverage for the restored waitForNames functionality. Consider adding a test case that:

    • Waits for a message name
    • Verifies it resolves when the message arrives
    • Tests abort signal behavior

🔐 Security Considerations

No security concerns identified. The abort signal handling prevents resource leaks and denial-of-service from accumulated listeners.


⚡ Performance Considerations

  1. Set operations: The code uses Set for name lookups (line 371, 381, 551), which is efficient O(1) for the contains check.

  2. Listener cleanup: Listeners are properly removed after resolution (line 381, 385, 540), preventing memory leaks.

  3. Minor optimization opportunity: In #notifyMessageListeners (line 547), the early return check is good. However, if waitForNames becomes heavily used with many different message names, you might consider optimizing by maintaining a reverse index (name → listeners) rather than iterating all listeners for each message. This is not necessary now but something to consider if performance becomes an issue.


📝 Documentation

  1. AGENTS.md rename: The symlink-to-file change for workflow-engine/AGENTS.md is fine, but it's unrelated to the queue fix. Consider splitting this into a separate commit for cleaner history (minor point).

  2. JSDoc comments: The restored waitForNames method has a brief JSDoc comment. Consider expanding it to document:

    • What happens if the actor is aborted
    • What happens if the abort signal is triggered
    • Example usage

🧪 Testing Recommendations

Add tests for:

  1. waitForNames resolves immediately if message exists
  2. waitForNames waits and resolves when message arrives
  3. waitForNames rejects when actor aborts
  4. waitForNames rejects when custom abort signal fires
  5. Multiple waiters for different message names work correctly
  6. Multiple waiters for the same message name all get resolved

✏️ Minor Suggestions

  1. actor-queue.ts:155: The optional chaining result?.status suggests result might be undefined in some cases. If this is expected, add a comment explaining when/why. If it's not expected, consider adding an assertion.

  2. Consistency: The MessageListener interface (line 59) follows the same pattern as QueueWaiter (line 40). Good consistency.


📊 Overall Assessment

Quality: ⭐⭐⭐⭐ (4/5)
Risk: 🟢 Low

This is a solid implementation that restores important functionality. The main improvements would be:

  1. Clarifying whether waitForNames should be exposed publicly
  2. Adding comprehensive test coverage
  3. Minor documentation improvements

The code is production-ready with the suggestion to add tests before merging.


✅ Recommendation

Approve with minor suggestions. Consider adding test coverage for the restored waitForNames functionality before merging.

@jog1t jog1t force-pushed the 02-04-fix_rivetkit_restore_waitfornames_and_fix_queue_type_errors branch from ee7f334 to a46d0d1 Compare February 4, 2026 21:58
@railway-app railway-app bot temporarily deployed to rivet-frontend / rivet-pr-4116 February 4, 2026 21:58 Destroyed
@jog1t jog1t force-pushed the 02-04-fix_rivetkit_restore_waitfornames_and_fix_queue_type_errors branch from a46d0d1 to 432fcd6 Compare February 4, 2026 22:11
@railway-app railway-app bot temporarily deployed to rivet-frontend / rivet-pr-4116 February 4, 2026 22:11 Destroyed
Comment on lines +403 to +413
if (abortSignal) {
const onAbort = () =>
listener.reject(new errors.ActorAborted());
if (abortSignal.aborted) {
onAbort();
return;
}
abortSignal.addEventListener("abort", onAbort, { once: true });
listener.signalAbortCleanup = () =>
abortSignal.removeEventListener("abort", onAbort);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Memory leak: When abortSignal is already aborted, the code calls onAbort() and returns early (lines 406-408). However, the actor abort signal listener was already registered (line 397) but never gets cleaned up because the listener hasn't been added to #messageListeners yet (line 415). The #removeMessageListener method only calls cleanup callbacks for listeners in the set.

Fix: Manually call cleanup before early return:

if (abortSignal.aborted) {
  listener.actorAbortCleanup?.();
  onAbort();
  return;
}
Suggested change
if (abortSignal) {
const onAbort = () =>
listener.reject(new errors.ActorAborted());
if (abortSignal.aborted) {
onAbort();
return;
}
abortSignal.addEventListener("abort", onAbort, { once: true });
listener.signalAbortCleanup = () =>
abortSignal.removeEventListener("abort", onAbort);
}
if (abortSignal) {
const onAbort = () =>
listener.reject(new errors.ActorAborted());
if (abortSignal.aborted) {
listener.actorAbortCleanup?.();
onAbort();
return;
}
abortSignal.addEventListener("abort", onAbort, { once: true });
listener.signalAbortCleanup = () =>
abortSignal.removeEventListener("abort", onAbort);
}

Spotted by Graphite Agent

Fix in Graphite


Is this helpful? React 👍 or 👎 to let us know.

@graphite-app
Copy link
Contributor

graphite-app bot commented Feb 5, 2026

Merge activity

  • Feb 5, 12:37 AM UTC: NathanFlurry added this pull request to the Graphite merge queue.
  • Feb 5, 12:37 AM UTC: CI is running for this pull request on a draft pull request (#4122) due to your merge queue CI optimization settings.
  • Feb 5, 12:38 AM UTC: Merged by the Graphite merge queue via draft PR: #4122.

graphite-app bot pushed a commit that referenced this pull request Feb 5, 2026
# Description

Please include a summary of the changes and the related issue. Please also include relevant motivation and context.

## Type of change

- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] This change requires a documentation update

## How Has This Been Tested?

Please describe the tests that you ran to verify your changes.

## Checklist:

- [ ] My code follows the style guidelines of this project
- [ ] I have performed a self-review of my code
- [ ] I have commented my code, particularly in hard-to-understand areas
- [ ] I have made corresponding changes to the documentation
- [ ] My changes generate no new warnings
- [ ] I have added tests that prove my fix is effective or that my feature works
- [ ] New and existing unit tests pass locally with my changes
@graphite-app graphite-app bot closed this Feb 5, 2026
@graphite-app graphite-app bot deleted the 02-04-fix_rivetkit_restore_waitfornames_and_fix_queue_type_errors branch February 5, 2026 00:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant