Repository navigation
lib,test: fix resuming channel writes after window adjustment - #1525
Open
shuxueshuxue wants to merge 1 commit into
Open
shuxueshuxue wants to merge 1 commit into
shuxueshuxue wants to merge 1 commit into
Conversation
When a channel write had to wait for the remote window, the remaining data was kept in `_chunk` (or `_chunkErr` for stderr) and written on the next CHANNEL_WINDOW_ADJUST. Two problems with that: * `_chunk` was never cleared after it was resumed, so if stderr later had to wait for the window, the next adjustment wrote the old stdout chunk again instead of resuming stderr. The stdout stream then contains duplicated bytes. * Only one of stdout/stderr was resumed per adjustment, so a stderr write waiting behind stdout was never resumed. Take both pending writes off the channel before resuming them, and resume stdout and stderr. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
When a channel write has to wait for the remote window, the remaining data is stored on the channel (
_chunkfor stdout,_chunkErrfor stderr) and written when the nextCHANNEL_WINDOW_ADJUSTarrives. The resume code in bothlib/client.jsandlib/server.jshas two problems:_chunkis never cleared after it is resumed. If stderr later has to wait for the window,_waitWindowis set again, and the next adjustment finds the old_chunkfirst and writes it again. The stdout stream then contains duplicated bytes, and its callback runs a second time.if (_chunk) … else if (_chunkErr) …), so a stderr write waiting behind stdout is never resumed.We hit this with a server-side exec channel carrying a length-prefixed binary protocol on stdout. Occasionally the client's decoder read a frame header from the middle of a payload, and stderr output never arrived.
Reproduction
The test added to
test/test-exec.jsdoes this:Before this change the test times out: stderr is never delivered, and stdout does not match what was written. With this change, stdout and stderr arrive intact.
Fix
Take both pending writes off the channel before resuming them, then resume stdout and stderr.
npm testandnpm run lintpass.