Conversation
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.
resize()can repeat terminal output and invoke write callbacks twice, either between write-processing slices or when called from a write callback. For example, a queuedgit statusecho followed by its output can render asgit statusgit status.This is a regression from #5599 ("Flush writes on resize"), introduced after stable 6.0.0.
_innerWrite()retains parsed chunks before_bufferOffsetwhen it yields, butflushSync()drains from index zero withshift(). A resize inside a write callback also sees the current chunk as pending because_innerWrite()has not advanced the offset yet.This PR drains from
_bufferOffsetand makes_innerWrite()update the offset and pending-data count before invoking the callback. Both resize paths then avoid replaying chunks or invoking their callbacks twice.The length-based loop also fixes data loss: an empty string currently stops the flush, permanently discarding all later queued output and outstanding callbacks.
write('', callback)is used to wait for queued writes to finish, including by Dormouse's productionflushTerminal(). A resize while that empty write is queued can leave its promise unresolved.The investigation started with an intermittent Dormouse snapshot failure. The headless regression reproduces the same doubled command by forcing a write-processing yield.
Related to #6154: this fixes its consumed-prefix replay, but leaves the separate async-parser failure unresolved. The maintainer discussion proposes removing resize's flush or making it stop at the first async handler; another contributor has been invited to work on that issue. Offset-aware draining is also needed for the latter approach; removing resize's flush would make this change unnecessary for that path. This PR is limited to queue bookkeeping and does not implement that broader change.
Test plan
npm run build && npm run esbuild,npm run test-unit,npm run lint, andnpm run lint-api.