From 2a60d7f8b00f61900bf38791a96a187867ca432d Mon Sep 17 00:00:00 2001 From: Megan Rogge Date: Fri, 26 Mar 2021 13:44:50 -0700 Subject: [PATCH] Enable terminal event batching from ptyHost (#117268) * fix #116468 Co-authored-by: Daniel Imms --- .../terminal/common/terminalDataBuffering.ts | 7 ++--- src/vs/platform/terminal/node/ptyService.ts | 29 +++++++++---------- 2 files changed, 16 insertions(+), 20 deletions(-) diff --git a/src/vs/platform/terminal/common/terminalDataBuffering.ts b/src/vs/platform/terminal/common/terminalDataBuffering.ts index ff1e611b93cfd..07d42978b80f2 100644 --- a/src/vs/platform/terminal/common/terminalDataBuffering.ts +++ b/src/vs/platform/terminal/common/terminalDataBuffering.ts @@ -31,17 +31,16 @@ export class TerminalDataBufferer implements IDisposable { let buffer = this._terminalBufferMap.get(id); if (buffer) { buffer.data.push(data); - return; } - const timeoutId = setTimeout(() => this._flushBuffer(id), throttleBy); + const timeoutId = setTimeout(() => this.flushBuffer(id), throttleBy); buffer = { data: [data], timeoutId: timeoutId, dispose: () => { clearTimeout(timeoutId); - this._flushBuffer(id); + this.flushBuffer(id); disposable.dispose(); } }; @@ -57,7 +56,7 @@ export class TerminalDataBufferer implements IDisposable { } } - private _flushBuffer(id: number): void { + flushBuffer(id: number): void { const buffer = this._terminalBufferMap.get(id); if (buffer) { this._terminalBufferMap.delete(id); diff --git a/src/vs/platform/terminal/node/ptyService.ts b/src/vs/platform/terminal/node/ptyService.ts index 3dfcaf8a5a5b6..121973445982c 100644 --- a/src/vs/platform/terminal/node/ptyService.ts +++ b/src/vs/platform/terminal/node/ptyService.ts @@ -12,6 +12,7 @@ import { TerminalRecorder } from 'vs/platform/terminal/common/terminalRecorder'; import { TerminalProcess } from 'vs/platform/terminal/node/terminalProcess'; import { ISetTerminalLayoutInfoArgs, ITerminalTabLayoutInfoDto, IProcessDetails, IGetTerminalLayoutInfoArgs, IPtyHostProcessReplayEvent } from 'vs/platform/terminal/common/terminalProcess'; import { ILogService } from 'vs/platform/log/common/log'; +import { TerminalDataBufferer } from 'vs/platform/terminal/common/terminalDataBuffering'; type WorkspaceId = string; @@ -224,7 +225,7 @@ export class PtyService extends Disposable implements IPtyService { export class PersistentTerminalProcess extends Disposable { - // private readonly _bufferer: TerminalDataBufferer; + private readonly _bufferer: TerminalDataBufferer; private readonly _pendingCommands = new Map void; reject: (err: any) => void; }>(); @@ -282,15 +283,6 @@ export class PersistentTerminalProcess extends Disposable { this.shutdown(true); }, LocalReconnectConstants.ReconnectionShortGraceTime)); - // TODO: Bring back bufferer - // this._bufferer = new TerminalDataBufferer((id, data) => { - // const ev: IPtyHostProcessDataEvent = { - // type: 'data', - // data: data - // }; - // this._events.fire(ev); - // }); - this._register(this._terminalProcess.onProcessReady(e => { this._pid = e.pid; this._cwd = e.cwd; @@ -298,12 +290,14 @@ export class PersistentTerminalProcess extends Disposable { })); this._register(this._terminalProcess.onProcessTitleChanged(e => this._onProcessTitleChanged.fire(e))); this._register(this._terminalProcess.onProcessShellTypeChanged(e => this._onProcessShellTypeChanged.fire(e))); - // Buffer data events to reduce the amount of messages going to the renderer - // this._register(this._bufferer.startBuffering(this._persistentProcessId, this._terminalProcess.onProcessData)); - this._register(this._terminalProcess.onProcessData(e => this._recorder.recordData(e))); - this._register(this._terminalProcess.onProcessExit(exitCode => { - // this._bufferer.stopBuffering(this._persistentProcessId); - })); + + // Data buffering to reduce the amount of messages going to the renderer + this._bufferer = new TerminalDataBufferer((_, data) => this._onProcessData.fire({ data: data, sync: true })); + this._register(this._bufferer.startBuffering(this._persistentProcessId, this._terminalProcess.onProcessData)); + this._register(this._terminalProcess.onProcessExit(() => this._bufferer.stopBuffering(this._persistentProcessId))); + + // Data recording for reconnect + this._register(this.onProcessData(e => this._recorder.recordData(e.data))); } attach(): void { @@ -348,6 +342,9 @@ export class PersistentTerminalProcess extends Disposable { return; } this._recorder.recordResize(cols, rows); + + // Buffered events should flush when a resize occurs + this._bufferer.flushBuffer(this._persistentProcessId); return this._terminalProcess.resize(cols, rows); } acknowledgeDataEvent(charCount: number): void {