Skip to content

Commit aa91e24

Browse files
committed
Include terminal replay in startup stats
Fixes microsoft#186068
1 parent 6a9dbdf commit aa91e24

File tree

7 files changed

+30
-11
lines changed

7 files changed

+30
-11
lines changed

src/vs/platform/terminal/common/terminal.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -680,6 +680,7 @@ export interface ITerminalChildProcess {
680680

681681
onProcessData: Event<IProcessDataEvent | string>;
682682
onProcessReady: Event<IProcessReadyEvent>;
683+
onProcessReplayComplete?: Event<void>;
683684
onDidChangeProperty: Event<IProcessProperty<any>>;
684685
onProcessExit: Event<number | undefined>;
685686
onRestoreCommands?: Event<ISerializedCommandDetectionCapability>;

src/vs/workbench/contrib/terminal/browser/terminal.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,7 @@ export interface ITerminalInstance {
536536
onDisposed: Event<ITerminalInstance>;
537537

538538
onProcessIdReady: Event<ITerminalInstance>;
539+
onProcessReplayComplete: Event<void>;
539540
onRequestExtHostProcess: Event<ITerminalInstance>;
540541
onDimensionsChanged: Event<void>;
541542
onMaximumDimensionsChanged: Event<void>;

src/vs/workbench/contrib/terminal/browser/terminalInstance.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,8 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
288288
readonly onDisposed = this._onDisposed.event;
289289
private readonly _onProcessIdReady = this._register(new Emitter<ITerminalInstance>());
290290
readonly onProcessIdReady = this._onProcessIdReady.event;
291+
private readonly _onProcessReplayComplete = this._register(new Emitter<void>());
292+
readonly onProcessReplayComplete = this._onProcessReplayComplete.event;
291293
private readonly _onTitleChanged = this._register(new Emitter<ITerminalInstance>());
292294
readonly onTitleChanged = this._onTitleChanged.event;
293295
private readonly _onIconChanged = this._register(new Emitter<{ instance: ITerminalInstance; userInitiated: boolean }>());
@@ -1395,6 +1397,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
13951397
this._initialDataEvents?.push(ev.data);
13961398
this._onData.fire(ev.data);
13971399
});
1400+
processManager.onProcessReplayComplete(() => this._onProcessReplayComplete.fire());
13981401
processManager.onEnvironmentVariableInfoChanged(e => this._onEnvironmentVariableInfoChanged(e));
13991402
processManager.onPtyDisconnect(() => {
14001403
if (this.xterm) {

src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce
108108
readonly onBeforeProcessData = this._onBeforeProcessData.event;
109109
private readonly _onProcessData = this._register(new Emitter<IProcessDataEvent>());
110110
readonly onProcessData = this._onProcessData.event;
111+
private readonly _onProcessReplayComplete = this._register(new Emitter<void>());
112+
readonly onProcessReplayComplete = this._onProcessReplayComplete.event;
111113
private readonly _onDidChangeProperty = this._register(new Emitter<IProcessProperty<any>>());
112114
readonly onDidChangeProperty = this._onDidChangeProperty.event;
113115
private readonly _onEnvironmentVariableInfoChange = this._register(new Emitter<IEnvironmentVariableInfo>());
@@ -375,10 +377,11 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce
375377
this._onDidChangeProperty.fire({ type, value });
376378
})
377379
];
380+
if (newProcess.onProcessReplayComplete) {
381+
this._processListeners.push(newProcess.onProcessReplayComplete(() => this._onProcessReplayComplete.fire()));
382+
}
378383
if (newProcess.onRestoreCommands) {
379-
this._processListeners.push(newProcess.onRestoreCommands(e => {
380-
this._onRestoreCommands.fire(e);
381-
}));
384+
this._processListeners.push(newProcess.onRestoreCommands(e => this._onRestoreCommands.fire(e)));
382385
}
383386
setTimeout(() => {
384387
if (this.processState === ProcessState.Launching) {

src/vs/workbench/contrib/terminal/browser/terminalService.ts

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ export class TerminalService implements ITerminalService {
9595
return this._detachedXterms;
9696
}
9797

98+
private _reconnectedTerminalGroups: Promise<ITerminalGroup[]> | undefined;
99+
98100
private _reconnectedTerminals: Map<string, ITerminalInstance[]> = new Map();
99101
getReconnectedTerminals(reconnectionOwner: string): ITerminalInstance[] | undefined {
100102
return this._reconnectedTerminals.get(reconnectionOwner);
@@ -292,6 +294,13 @@ export class TerminalService implements ITerminalService {
292294
reconnectedPromise.then(async () => {
293295
this._setConnected();
294296
mark('code/terminal/didReconnect');
297+
mark('code/terminal/willReplay');
298+
const instances = await this._reconnectedTerminalGroups?.then(groups => groups.map(e => e.terminalInstances).flat()) ?? [];
299+
await Promise.all(instances.map(e => new Promise<void>(r => Event.once(e.onProcessReplayComplete)(() => {
300+
mark(`code/terminal/replay/${e.shellLaunchConfig.attachPersistentProcess?.id}`);
301+
r();
302+
}))));
303+
mark('code/terminal/didReplay');
295304
for (const backend of this._terminalInstanceService.getRegisteredBackends()) {
296305
mark('code/terminal/willGetPerformanceMarks');
297306
this._timerService.setPerformanceMarks(backend.remoteAuthority === undefined ? 'localPtyHost' : 'remotePtyHost', await backend.getPerformanceMarks());
@@ -450,25 +459,25 @@ export class TerminalService implements ITerminalService {
450459
mark('code/terminal/didGetTerminalLayoutInfo');
451460
if (layoutInfo && layoutInfo.tabs.length > 0) {
452461
mark('code/terminal/willRecreateTerminalGroups');
453-
this._restoredGroupCount = await this._recreateTerminalGroups(layoutInfo);
462+
this._reconnectedTerminalGroups = this._recreateTerminalGroups(layoutInfo);
454463
mark('code/terminal/didRecreateTerminalGroups');
455464
}
456465
// now that terminals have been restored,
457466
// attach listeners to update local state when terminals are changed
458467
this._attachProcessLayoutListeners();
459468
}
460469

461-
private async _recreateTerminalGroups(layoutInfo?: ITerminalsLayoutInfo): Promise<number> {
470+
private _recreateTerminalGroups(layoutInfo?: ITerminalsLayoutInfo): Promise<ITerminalGroup[]> {
471+
const groupPromises: Promise<ITerminalGroup | undefined>[] = [];
462472
let reconnectCounter = 0;
463473
let activeGroup: Promise<ITerminalGroup | undefined> | undefined;
464474
if (layoutInfo) {
465-
const tabPromises: Promise<ITerminalGroup | undefined>[] = [];
466475
for (const tabLayout of layoutInfo.tabs) {
467476
const terminalLayouts = tabLayout.terminals.filter(t => t.terminal && t.terminal.isOrphan);
468477
if (terminalLayouts.length) {
469478
reconnectCounter += terminalLayouts.length;
470479
const promise = this._recreateTerminalGroup(tabLayout, terminalLayouts);
471-
tabPromises.push(promise);
480+
groupPromises.push(promise);
472481
if (tabLayout.isActive) {
473482
activeGroup = promise;
474483
}
@@ -482,7 +491,7 @@ export class TerminalService implements ITerminalService {
482491
activeGroup?.then(group => this._terminalGroupService.activeGroup = group);
483492
}
484493
}
485-
return reconnectCounter;
494+
return Promise.all(groupPromises).then(result => result.filter(e => !!e) as ITerminalGroup[]);
486495
}
487496

488497
private async _recreateTerminalGroup(tabLayout: IRawTerminalTabLayoutInfo<IPtyHostAttachTarget | null>, terminalLayouts: IRawTerminalInstanceLayoutInfo<IPtyHostAttachTarget | null>[]): Promise<ITerminalGroup | undefined> {
@@ -502,7 +511,6 @@ export class TerminalService implements ITerminalService {
502511
});
503512
group = lastInstance.then(instance => this._terminalGroupService.getGroupForInstance(instance));
504513
} else {
505-
// TODO: Make parentInstance a promise?
506514
// add split terminals to this group
507515
lastInstance = this.createTerminal({
508516
config: { attachPersistentProcess },

src/vs/workbench/contrib/terminal/common/terminal.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,7 @@ export interface ITerminalProcessManager extends IDisposable {
280280
readonly onProcessReady: Event<IProcessReadyEvent>;
281281
readonly onBeforeProcessData: Event<IBeforeProcessDataEvent>;
282282
readonly onProcessData: Event<IProcessDataEvent>;
283+
readonly onProcessReplayComplete: Event<void>;
283284
readonly onEnvironmentVariableInfoChanged: Event<IEnvironmentVariableInfo>;
284285
readonly onDidChangeProperty: Event<IProcessProperty<any>>;
285286
readonly onProcessExit: Event<number | undefined>;

src/vs/workbench/contrib/terminal/electron-sandbox/localPty.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ export class LocalPty extends Disposable implements ITerminalChildProcess {
3232

3333
private readonly _onProcessData = this._register(new Emitter<IProcessDataEvent | string>());
3434
readonly onProcessData = this._onProcessData.event;
35-
private readonly _onProcessReplay = this._register(new Emitter<IPtyHostProcessReplayEvent>());
36-
readonly onProcessReplay = this._onProcessReplay.event;
35+
private readonly _onProcessReplayComplete = this._register(new Emitter<void>());
36+
readonly onProcessReplayComplete = this._onProcessReplayComplete.event;
3737
private readonly _onProcessReady = this._register(new Emitter<IProcessReadyEvent>());
3838
readonly onProcessReady = this._onProcessReady.event;
3939
private readonly _onDidChangeProperty = this._register(new Emitter<IProcessProperty<any>>());
@@ -162,6 +162,8 @@ export class LocalPty extends Disposable implements ITerminalChildProcess {
162162

163163
// remove size override
164164
this._onDidChangeProperty.fire({ type: ProcessPropertyType.OverrideDimensions, value: undefined });
165+
166+
this._onProcessReplayComplete.fire();
165167
}
166168

167169
handleOrphanQuestion() {

0 commit comments

Comments
 (0)