Skip to content

Control sequence bytes in stdout causing non-functional performance issues in distributed shell environments #24696

Closed

Description

Prerequisites

Steps to reproduce

Reproducing the issue is not extremely easy, so before we invest a lot of time into standing up a git repository with reproducible artifacts, we wanted to get the issue out there and simply explain with screenshots. It is a non-functional issue that we believe was introduced by design changes made to the way stdout is processed in the latest 7.4 runtime, but we cannot be certain.

Essentially, the high-level reproduction of the issue is done by doing the following:

  1. Create a node app
  2. Install node-pty
  3. Install express with a basic route to render a simple HTML page
  4. Install xtermjs
  5. Upon loading of web page, open a websocket
  6. In websocket connect handler, fork pwsh process with node-pty
  7. Setup stdin/stdout handlers to sync the websocket and pwsh process
  8. Configure the front-end xtermjs terminal to bind to the websocket

At this point you have a fully working pwsh terminal in the front-end. We understand the above is very hand-wavy and the setup for this is not entirely trivial.

  1. Paste in some text, such as "abcdefghijklmnop" to the terminal

Observe substantial difference in total round trips of websocket performing various control character seqeunces. (See attached screenshots for example of differences performing the copy/paste from step 8)

In a low latency environment, this appears to be a non-issue (e.g. when the process is hosted on the same machine as the client), but in a production environment where the client connects to a transient process hosted on a unix container running nodejs in an Azure Datacenter, the latency between stdin/stdout becomes substantial.

We want to at least get some eyes on this as it is a bit of complicated issue and there are some non-PowerShell components at play in the reproduction of the issue (the fact that the issue is really only noticed in a high-latency env where the client shell and process are hosted seperately)

Patrick Meinecke (@SeeminglyScience), tagging you as you appear to be highly knowlegeable of the changes introduced around native command byte stream processing to stdout and the experimental features that have gone into stable release of 7.4. We have no proof that this is related to these changes, but the nature of their domain make us think it is a possibility. Curious if anything here seems familiar or could be suspect for investigation. Thanks!

Expected behavior

I am not sure we can consider this a bug and therefore can expect the behavior to be as it was before. Assuming this new behavior related to the control sequences observed in stdout is by-design, it would likely require a re-design of these efforts to minimize the behavior.

Actual behavior

Control seqeunce goes back to simplified version or at least has a way to "opt-in" to old behavior if possible.

Error details

No response

Environment data

Name                           Value
----                           -----
PSVersion                      7.4.6
PSEdition                      Core
GitCommitId                    7.4.6
OS                             Ubuntu 22.04.5 LTS
Platform                       Unix
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

Visuals

Before (7.2)

Observe the total round trip between client and server requires only 4 total messages being sent.

Unlikely the below example, the host process doesn't send each individual byte that was pasted in one at a time back to the client, instead it processes all bytes at once and returns the entire, aggregated stdout as one single buffer making it much more performant.
image

After (7.4)

Observe that now, every individual character that was pasted into the terminal requires an entire round-trip to the server process where the entire shell buffer of all bytes on the screen are returned, then some kind of "control" byte is sent back to the host process and then the next set of the entire shell buffer is sent again, this time with 1 more character. You can see the "Length" of the message grows by 1 byte each time indicating that the bytes being pasted are being sent back individually. So if you were to paste simply "abc" into the terminal, the host process would send back something like this:

  1. myshellprompt>a sent to client (with ansi-color bytes too)
  2. Control character sent to server
  3. myshellprompt>ab snet to client
  4. Control character sent to server
  5. myshellprompt>abc sent to client
  6. Control character sent to server

The problem is exacerbated by pasting longer strings of text as the total buffer size increased and the message latency increases
image

Activity

  1. mhintzke commented on Dec 20, 2024

    @mhintzke
    Author

    Hey TylerLeonhardt!

    You probably don't remember me, but you helped my team and I a number of years ago when we were first innovating on our product that utilizes PSES over websockets + Monaco Editor and I know you are heavily involved with PowerShell and VSCode in general. I am curious if your team has experienced anything like this in VSCode and the xterm implementation utilized there? I know generally VSCode uses a native process to host PowerShell for it's terminals, but if there is any kind of "remoting" capability with the terminal where the VSCode process running the xterm component and the underlying pwsh process are hosted independently, then this issue maybe reproducible in VSCode as well.

  2. SeeminglyScience commented on Dec 20, 2024

    @SeeminglyScience
    Contributor

    So the changes to native command processing is definitely not in play here. That would only potentially be an issue if you were running a shell inside pwsh and also redirecting it's stdout (directly, not through a pty). That can pretty safely be ruled out.

    More likely this is a change in how PSReadLine is rendering. I would try updating the PSReadLine module version in your 7.2 test and see if it gets the same results as your 7.4 test

  3. mhintzke commented on Dec 20, 2024

    @mhintzke
    Author

    Patrick Meinecke (@SeeminglyScience) Ok great, it felt like that was the case, but just simply due to the fact those changes were related to processing of stdout, I had to ask. Thanks a lot!

    And I will definitely give the PSReadLine module an update and see if that causes the issue to reproduce. Appreciate the suggestion.

  4. jhoneill commented on Dec 21, 2024

    @jhoneill

    More likely this is a change in how PSReadLine is rendering. I would try updating the PSReadLine module version in your 7.2 test and see if it gets the same results as your 7.4 test

    Or try remove-module psreadline on 7.4. That would seem to be a quick way to do before and after tests.

  5. SeeminglyScience commented on Dec 23, 2024

    @SeeminglyScience
    Contributor

    Removing PSReadLine would just result in no VT sequences (at least no color related VTs) and also a different REPL rendering implementation (a very basic one). Probably not going to help narrow things down in this case.

  6. mhintzke commented on Jan 6, 2025

    @mhintzke
    Author

    Patrick Meinecke (@SeeminglyScience)

    I was able to confirm that the offending release of PSReadLine module is this one:

    https://github.com/PowerShell/PSReadLine/releases/tag/v2.2.0-beta5

    When I transition from v2.2.0-beta4 to v2.2.0-beta5, the change in the buffer occurs and causes the latency issues. So this has definitely been around for a while for anyone using PowerShell 7.3.0 and above according to this:
    image

    I am going to start with looking at some of the code and then creating an issue on that repository instead. Thanks again!

    GitHub
    2.2.0-beta5 - 2022-01-06 You can get the v2.2.0-beta5 version of the PSReadLine module from PowerShell Gallery. This release includes the following changes:

    Improve RecomputeInitialCoords to be mo...

  7. microsoft-github-policy-service commented on Jan 6, 2025

    @microsoft-github-policy-service
    Contributor

    📣 Hey Matthew Hintzke (@mhintzke), how did we do? We would love to hear your feedback with the link below! 🗣️

    🔗 https://aka.ms/PSRepoFeedback

  8. mhintzke commented on Jan 6, 2025

    @mhintzke
    Author

    I ended up finding a similar issue here that hasn't been addressed

    PowerShell/PSReadLine#3879

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions