From a16bcb8e48d4306ede9040f9bdef96ec275ea5c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=A4der?= Date: Thu, 6 Oct 2022 20:30:42 +0200 Subject: [PATCH] Add support for lifecycleManagedByParent. Fixes #11511 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Forwards lifecycle events to parent session where applicable and changes the behavior of compound sessions to behave same way. Contributed on behalf of ST Microelectronics Signed-off-by: Thomas Mäder --- .../src/browser/debug-session-manager.ts | 33 +++++++++++++++---- packages/debug/src/browser/debug-session.tsx | 6 ---- .../debug/src/common/debug-configuration.ts | 3 ++ packages/plugin/src/theia.d.ts | 7 ++++ 4 files changed, 37 insertions(+), 12 deletions(-) diff --git a/packages/debug/src/browser/debug-session-manager.ts b/packages/debug/src/browser/debug-session-manager.ts index 580e479cb0636..46d6ea6dd2090 100644 --- a/packages/debug/src/browser/debug-session-manager.ts +++ b/packages/debug/src/browser/debug-session-manager.ts @@ -250,8 +250,9 @@ export class DebugSessionManager { protected async startCompound(options: DebugCompoundSessionOptions): Promise { let configurations: DebugConfigurationSessionOptions[] = []; + const compoundRoot = options.compound.stopAll ? new DebugCompoundRoot() : undefined; try { - configurations = this.getCompoundConfigurations(options); + configurations = this.getCompoundConfigurations(options, compoundRoot); } catch (error) { this.messageService.error(error.message); return; @@ -265,19 +266,25 @@ export class DebugSessionManager { } // Compound launch is a success only if each configuration launched successfully - const values = await Promise.all(configurations.map(configuration => this.startConfiguration(configuration))); + const values = await Promise.all(configurations.map(async configuration => { + const newSession = await this.startConfiguration(configuration); + if (newSession) { + compoundRoot?.onDidSessionStop(() => newSession.stop(false, () => this.debug.terminateDebugSession(newSession.id))); + } + return newSession; + })); const result = values.every(success => !!success); return result; } - protected getCompoundConfigurations(options: DebugCompoundSessionOptions): DebugConfigurationSessionOptions[] { + protected getCompoundConfigurations(options: DebugCompoundSessionOptions, compoundRoot: DebugCompoundRoot | undefined): DebugConfigurationSessionOptions[] { const compound = options.compound; if (!compound.configurations) { throw new Error(nls.localizeByDefault('Compound must have "configurations" attribute set in order to start multiple configurations.')); } - const compoundRoot = compound.stopAll ? new DebugCompoundRoot() : undefined; const configurations: DebugConfigurationSessionOptions[] = []; + for (const configData of compound.configurations) { const name = typeof configData === 'string' ? configData : configData.name; if (name === compound.name) { @@ -431,6 +438,7 @@ export class DebugSessionManager { await session.restart(); return session; } + const { options, configuration } = session; session.stop(isRestart, () => this.debug.terminateDebugSession(session.id)); configuration.__restart = isRestart; @@ -443,7 +451,15 @@ export class DebugSessionManager { session = this._currentSession; } if (session) { - session.stop(false, () => this.debug.terminateDebugSession(session!.id)); + if (session.options.compoundRoot) { + session.options.compoundRoot.stopSession(); + } else { + if (session.parentSession && session.configuration.lifecycleManagedByParent) { + this.terminateSession(session.parentSession); + } else { + session.stop(false, () => this.debug.terminateDebugSession(session!.id)); + } + } } } @@ -452,8 +468,13 @@ export class DebugSessionManager { this.updateCurrentSession(this._currentSession); session = this._currentSession; } + if (session) { - return this.doRestart(session, true); + if (session.parentSession && session.configuration.lifecycleManagedByParent) { + return this.restartSession(session.parentSession); + } else { + return this.doRestart(session, true); + } } } diff --git a/packages/debug/src/browser/debug-session.tsx b/packages/debug/src/browser/debug-session.tsx index a43b09ded9a61..fbf9dfc238db4 100644 --- a/packages/debug/src/browser/debug-session.tsx +++ b/packages/debug/src/browser/debug-session.tsx @@ -117,9 +117,6 @@ export class DebugSession implements CompositeTreeElement { this.connection.on('capabilities', event => this.updateCapabilities(event.body.capabilities)), this.breakpoints.onDidChangeMarkers(uri => this.updateBreakpoints({ uri, sourceModified: true })) ]); - if (this.options.compoundRoot) { - this.toDispose.push(this.options.compoundRoot.onDidSessionStop(() => this.stop(false, () => { }))); - } } get onDispose(): Event { @@ -355,9 +352,6 @@ export class DebugSession implements CompositeTreeElement { console.error('Error on disconnect', e); } } - if (!isRestart) { - this.options.compoundRoot?.stopSession(); - } callback(); } } diff --git a/packages/debug/src/common/debug-configuration.ts b/packages/debug/src/common/debug-configuration.ts index 6abd0a8a725d6..8eb3ea4232f91 100644 --- a/packages/debug/src/common/debug-configuration.ts +++ b/packages/debug/src/common/debug-configuration.ts @@ -37,6 +37,8 @@ export interface DebugConfiguration { parentSession?: { id: string }; + lifecycleManagedByParent?: boolean; + consoleMode?: DebugConsoleMode; compact?: boolean; @@ -77,6 +79,7 @@ export namespace DebugConfiguration { } export interface DebugSessionOptions { + lifecycleManagedByParent?: boolean; parentSession?: { id: string }; consoleMode?: DebugConsoleMode; noDebug?: boolean; diff --git a/packages/plugin/src/theia.d.ts b/packages/plugin/src/theia.d.ts index 8af9cbba54cbc..87169689a2209 100644 --- a/packages/plugin/src/theia.d.ts +++ b/packages/plugin/src/theia.d.ts @@ -10269,6 +10269,13 @@ export module '@theia/plugin' { */ parentSession?: DebugSession; + /** + * Controls whether lifecycle requests like 'restart' are sent to the newly created session or its parent session. + * By default (if the property is false or missing), lifecycle requests are sent to the new session. + * This property is ignored if the session has no parent session. + */ + lifecycleManagedByParent?: boolean; + /** * Controls whether this session should have a separate debug console or share it * with the parent session. Has no effect for sessions which do not have a parent session.