-
Notifications
You must be signed in to change notification settings - Fork 37.2k
Description
@Jarred-Sumner pointed out in https://x.com/jarredsumner/status/1999317065237512224 this throttling mechanism on paste/sendText (my response at https://x.com/Tyriar/status/1999487637674147925):
vscode/src/vs/platform/terminal/node/terminalProcess.ts
Lines 473 to 481 in f83b278
| input(data: string, isBinary: boolean = false): void { | |
| if (this._store.isDisposed || !this._ptyProcess) { | |
| return; | |
| } | |
| this._writeQueue.push(...chunkInput(data).map(e => { | |
| return { isBinary, data: e }; | |
| })); | |
| this._startWrite(); | |
| } |
vscode/src/vs/platform/terminal/node/terminalProcess.ts
Lines 525 to 544 in f83b278
| private _startWrite(): void { | |
| // Don't write if it's already queued of is there is nothing to write | |
| if (this._writeTimeout !== undefined || this._writeQueue.length === 0) { | |
| return; | |
| } | |
| this._doWrite(); | |
| // Don't queue more writes if the queue is empty | |
| if (this._writeQueue.length === 0) { | |
| this._writeTimeout = undefined; | |
| return; | |
| } | |
| // Queue the next write | |
| this._writeTimeout = setTimeout(() => { | |
| this._writeTimeout = undefined; | |
| this._startWrite(); | |
| }, Constants.WriteInterval); | |
| } |
vscode/src/vs/platform/terminal/common/terminalProcess.ts
Lines 73 to 109 in f83b278
| const enum Constants { | |
| /** | |
| * Writing large amounts of data can be corrupted for some reason, after looking into this is | |
| * appears to be a race condition around writing to the FD which may be based on how powerful | |
| * the hardware is. The workaround for this is to space out when large amounts of data is being | |
| * written to the terminal. See https://github.com/microsoft/vscode/issues/38137 | |
| */ | |
| WriteMaxChunkSize = 50, | |
| } | |
| /** | |
| * Splits incoming pty data into chunks to try prevent data corruption that could occur when pasting | |
| * large amounts of data. | |
| */ | |
| export function chunkInput(data: string): string[] { | |
| const chunks: string[] = []; | |
| let nextChunkStartIndex = 0; | |
| for (let i = 0; i < data.length - 1; i++) { | |
| if ( | |
| // If the max chunk size is reached | |
| i - nextChunkStartIndex + 1 >= Constants.WriteMaxChunkSize || | |
| // If the next character is ESC, send the pending data to avoid splitting the escape | |
| // sequence. | |
| data[i + 1] === '\x1b' | |
| ) { | |
| chunks.push(data.substring(nextChunkStartIndex, i + 1)); | |
| nextChunkStartIndex = i + 1; | |
| // Skip the next character as the chunk would be a single character | |
| i++; | |
| } | |
| } | |
| // Push final chunk | |
| if (nextChunkStartIndex !== data.length) { | |
| chunks.push(data.substring(nextChunkStartIndex)); | |
| } | |
| return chunks; | |
| } |
This was added as one of the attempts to try fix an issue where sending large amounts of data to the terminal would drop chunks of it #38137
This comment is the most relevant explanation as to why I thought this was happening at the time. I believe I was also never able to reproduce the problem on my machine:
vscode/src/vs/platform/terminal/common/terminalProcess.ts
Lines 73 to 81 in f83b278
| const enum Constants { | |
| /** | |
| * Writing large amounts of data can be corrupted for some reason, after looking into this is | |
| * appears to be a race condition around writing to the FD which may be based on how powerful | |
| * the hardware is. The workaround for this is to space out when large amounts of data is being | |
| * written to the terminal. See https://github.com/microsoft/vscode/issues/38137 | |
| */ | |
| WriteMaxChunkSize = 50, | |
| } |
The justification for the original fix is that correctness is much more important than performance here as pasting large amounts of data like this is an edge case, at least in a terminal within an editor. It sucks though so we should fix it.