Skip to content

Conversation

@bbopen
Copy link
Owner

@bbopen bbopen commented Jan 21, 2026

Summary

Improve ProcessIO transport resilience with:

Changes

  • Add markForRestart() method to trigger process restart on next send
  • Add handleStdoutError() and handleStderrError() handlers
  • Add writeQueueTimeoutMs option (default: 30000ms)
  • Track queuedAt timestamp for each queued write
  • Call markForRestart() after all write/stream error paths

Test plan

  • All 1225 tests pass
  • Build and typecheck pass
  • ProcessIO-related tests (runtime_node, runtime_bridge_fixtures) pass

Fixes #107, #91, #59

🤖 Generated with Claude Code

…meout

Improve ProcessIO transport resilience with:

1. Auto-restart on write failures (#107)
   - Add markForRestart() method to trigger process restart on next send
   - Call markForRestart() after stdin write errors, EPIPE, and queue failures

2. Add stdout/stderr error handlers (#91)
   - Add handleStdoutError() and handleStderrError() methods
   - Register error handlers in spawnProcess() to prevent unhandled crashes
   - Reject pending requests and mark for restart on stream errors

3. Add write queue timeout (#59)
   - Add writeQueueTimeoutMs option (default: 30000ms)
   - Track queuedAt timestamp for each queued write
   - Reject timed-out writes in flushWriteQueue() with BridgeTimeoutError

Fixes #107, #91, #59

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@coderabbitai
Copy link

coderabbitai bot commented Jan 21, 2026

Warning

Rate limit exceeded

@bbopen has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 15 minutes and 5 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, 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 have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between dc506a8 and 600dfac.

📒 Files selected for processing (1)
  • src/runtime/process-io.ts

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.


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

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6b6dfc0e46

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

1. Fix markForRestart() no-op when restartAfterRequests=0
   - Added needsRestart flag that works independently
   - Restart check now checks: needsRestart || scheduled restart

2. Fix write queue timeout not firing without drain event
   - Added createQueuedWrite() helper with timeout timer
   - Timer fires after writeQueueTimeoutMs even if drain never happens
   - Timer is unref'd so it doesn't keep process alive
   - Timeouts cleared properly on resolve/reject/dispose

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@bbopen
Copy link
Owner Author

bbopen commented Jan 21, 2026

Addressed Codex Review Feedback

Both issues identified by Codex have been fixed in commit 600dfac:

1. markForRestart() no-op fix

Problem: When restartAfterRequests=0 (the default), markForRestart() was a no-op because it set requestCount = restartAfterRequests, which doesn't trigger a restart when the setting is 0.

Solution: Added a separate needsRestart flag that works independently of restartAfterRequests. The restart check now evaluates:

if (this.needsRestart || (this.restartAfterRequests > 0 && this.requestCount >= this.restartAfterRequests))

2. Write queue timeout timer fix

Problem: The write queue timeout only fired when flushWriteQueue() was called during a drain event. If drain never happened (e.g., process hung, stdin buffer full forever), entries would sit in the queue indefinitely.

Solution: Added a timer-based timeout mechanism:

  • createQueuedWrite() creates entries with a timeout timer that fires after writeQueueTimeoutMs
  • The timer is unref()'d so it doesn't keep the process alive
  • Timeouts are properly cleared on resolve/reject/dispose
  • The drain-based check remains as a fallback safety measure

Both fixes ensure stream errors and write queue issues are handled correctly regardless of configuration.

@bbopen bbopen merged commit 2909293 into main Jan 21, 2026
19 of 20 checks passed
@bbopen bbopen deleted the feat/process-io-hardening branch January 21, 2026 18:32
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.

NodeBridge should reset process after stdin write failures

2 participants