Implement terminal replay event
This commit is contained in:
parent
3f7b91e2e2
commit
4de2511162
@ -1466,10 +1466,10 @@ index 0000000000000000000000000000000000000000..6ce56bec114a6d8daf5dd3ded945ea78
|
|||||||
+}
|
+}
|
||||||
diff --git a/src/vs/server/node/channel.ts b/src/vs/server/node/channel.ts
|
diff --git a/src/vs/server/node/channel.ts b/src/vs/server/node/channel.ts
|
||||||
new file mode 100644
|
new file mode 100644
|
||||||
index 0000000000000000000000000000000000000000..91a932b613c473cd13dfddbde2942aeebf4bb84c
|
index 0000000000000000000000000000000000000000..cb3a45fda10a6bcbff73275b5734641b3319cc9b
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/src/vs/server/node/channel.ts
|
+++ b/src/vs/server/node/channel.ts
|
||||||
@@ -0,0 +1,780 @@
|
@@ -0,0 +1,828 @@
|
||||||
+import { field, logger } from '@coder/logger';
|
+import { field, logger } from '@coder/logger';
|
||||||
+import { Server } from '@coder/node-browser';
|
+import { Server } from '@coder/node-browser';
|
||||||
+import * as os from 'os';
|
+import * as os from 'os';
|
||||||
@ -1884,6 +1884,14 @@ index 0000000000000000000000000000000000000000..91a932b613c473cd13dfddbde2942aee
|
|||||||
+ private readonly _onDispose = new Emitter<void>();
|
+ private readonly _onDispose = new Emitter<void>();
|
||||||
+ public get onDispose(): Event<void> { return this._onDispose.event; }
|
+ public get onDispose(): Event<void> { return this._onDispose.event; }
|
||||||
+
|
+
|
||||||
|
+ // These are replayed when a client reconnects.
|
||||||
|
+ private cols: number;
|
||||||
|
+ private rows: number;
|
||||||
|
+ private replayData: string[] = [];
|
||||||
|
+ // This is based on string length and is pretty arbitrary.
|
||||||
|
+ private readonly maxReplayData = 10000;
|
||||||
|
+ private totalReplayData = 0;
|
||||||
|
+
|
||||||
+ private buffering = false;
|
+ private buffering = false;
|
||||||
+ private readonly _onEvent = new Emitter<terminal.IRemoteTerminalProcessEvent>({
|
+ private readonly _onEvent = new Emitter<terminal.IRemoteTerminalProcessEvent>({
|
||||||
+ // Don't bind to data until something is listening.
|
+ // Don't bind to data until something is listening.
|
||||||
@ -1894,6 +1902,23 @@ index 0000000000000000000000000000000000000000..91a932b613c473cd13dfddbde2942aee
|
|||||||
+ this.bufferer.startBuffering(this.id, this.process.onProcessData);
|
+ this.bufferer.startBuffering(this.id, this.process.onProcessData);
|
||||||
+ }
|
+ }
|
||||||
+ },
|
+ },
|
||||||
|
+
|
||||||
|
+ // Replay stored events.
|
||||||
|
+ onFirstListenerDidAdd: () => {
|
||||||
|
+ if (this.replayData.length === 0) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ logger.debug('Terminal replaying', field('id', this.id));
|
||||||
|
+ this._onEvent.fire({
|
||||||
|
+ type: 'replay',
|
||||||
|
+ events: [{
|
||||||
|
+ cols: this.cols,
|
||||||
|
+ rows: this.rows,
|
||||||
|
+ data: this.replayData.join(""),
|
||||||
|
+ }]
|
||||||
|
+ });
|
||||||
|
+ }
|
||||||
+ });
|
+ });
|
||||||
+
|
+
|
||||||
+ public get onEvent(): Event<terminal.IRemoteTerminalProcessEvent> { return this._onEvent.event; }
|
+ public get onEvent(): Event<terminal.IRemoteTerminalProcessEvent> { return this._onEvent.event; }
|
||||||
@ -1904,6 +1929,33 @@ index 0000000000000000000000000000000000000000..91a932b613c473cd13dfddbde2942aee
|
|||||||
+ type: 'data',
|
+ type: 'data',
|
||||||
+ data,
|
+ data,
|
||||||
+ });
|
+ });
|
||||||
|
+
|
||||||
|
+ this.replayData.push(data);
|
||||||
|
+ this.totalReplayData += data.length;
|
||||||
|
+
|
||||||
|
+ let overflow = this.totalReplayData - this.maxReplayData;
|
||||||
|
+ if (overflow <= 0) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // Drop events until doing so would put us under budget.
|
||||||
|
+ let deleteCount = 0;
|
||||||
|
+ for (; deleteCount < this.replayData.length
|
||||||
|
+ && this.replayData[deleteCount].length <= overflow; ++deleteCount) {
|
||||||
|
+ overflow -= this.replayData[deleteCount].length;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (deleteCount > 0) {
|
||||||
|
+ this.replayData.splice(0, deleteCount);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // Dropping any more events would put us under budget; trim the first event
|
||||||
|
+ // instead if still over budget.
|
||||||
|
+ if (overflow > 0 && this.replayData.length > 0) {
|
||||||
|
+ this.replayData[0] = this.replayData[0].substring(overflow);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ this.totalReplayData = this.replayData.reduce((p, c) => p + c.length, 0);
|
||||||
+ });
|
+ });
|
||||||
+
|
+
|
||||||
+ public get pid(): number {
|
+ public get pid(): number {
|
||||||
@ -1924,11 +1976,14 @@ index 0000000000000000000000000000000000000000..91a932b613c473cd13dfddbde2942aee
|
|||||||
+ this.workspaceId = args.workspaceId;
|
+ this.workspaceId = args.workspaceId;
|
||||||
+ this.workspaceName = args.workspaceName;
|
+ this.workspaceName = args.workspaceName;
|
||||||
+
|
+
|
||||||
|
+ this.cols = args.cols;
|
||||||
|
+ this.rows = args.rows;
|
||||||
|
+
|
||||||
+ this.process = new TerminalProcess(
|
+ this.process = new TerminalProcess(
|
||||||
+ config,
|
+ config,
|
||||||
+ config.cwd,
|
+ config.cwd,
|
||||||
+ args.cols,
|
+ this.cols,
|
||||||
+ args.rows,
|
+ this.rows,
|
||||||
+ env,
|
+ env,
|
||||||
+ process.env as platform.IProcessEnvironment, // Environment used for `findExecutable`.
|
+ process.env as platform.IProcessEnvironment, // Environment used for `findExecutable`.
|
||||||
+ false, // windowsEnableConpty: boolean,
|
+ false, // windowsEnableConpty: boolean,
|
||||||
@ -1962,10 +2017,6 @@ index 0000000000000000000000000000000000000000..91a932b613c473cd13dfddbde2942aee
|
|||||||
+ this.dispose();
|
+ this.dispose();
|
||||||
+ });
|
+ });
|
||||||
+
|
+
|
||||||
+ // TODO: replay event
|
|
||||||
+ // type: 'replay';
|
|
||||||
+ // events: ReplayEntry[];
|
|
||||||
+
|
|
||||||
+ // TODO: exec command event
|
+ // TODO: exec command event
|
||||||
+ // type: 'execCommand';
|
+ // type: 'execCommand';
|
||||||
+ // reqId: number;
|
+ // reqId: number;
|
||||||
@ -1977,9 +2028,11 @@ index 0000000000000000000000000000000000000000..91a932b613c473cd13dfddbde2942aee
|
|||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ public dispose() {
|
+ public dispose() {
|
||||||
|
+ logger.debug('Terminal disposing', field('id', this.id));
|
||||||
+ this._onEvent.dispose();
|
+ this._onEvent.dispose();
|
||||||
+ this.bufferer.dispose();
|
+ this.bufferer.dispose();
|
||||||
+ this.process.dispose();
|
+ this.process.dispose();
|
||||||
|
+ this.process.shutdown(true);
|
||||||
+ this._onDispose.fire();
|
+ this._onDispose.fire();
|
||||||
+ this._onDispose.dispose();
|
+ this._onDispose.dispose();
|
||||||
+ }
|
+ }
|
||||||
@ -2005,6 +2058,8 @@ index 0000000000000000000000000000000000000000..91a932b613c473cd13dfddbde2942aee
|
|||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ public resize(cols: number, rows: number): void {
|
+ public resize(cols: number, rows: number): void {
|
||||||
|
+ this.cols = cols;
|
||||||
|
+ this.rows = rows;
|
||||||
+ return this.process.resize(cols, rows);
|
+ return this.process.resize(cols, rows);
|
||||||
+ }
|
+ }
|
||||||
+}
|
+}
|
||||||
|
Reference in New Issue
Block a user