Skip to content

Commit 0ef5dff

Browse files
authored
Adopt new extension host restart lifecycle (microsoft#180514) (microsoft#183293)
* Adopt new extension host restart lifecycle (microsoft#180514) * adopt for notebooks * fix tests
1 parent 49f7ecf commit 0ef5dff

File tree

8 files changed

+33
-23
lines changed

8 files changed

+33
-23
lines changed

src/vs/workbench/contrib/extensions/browser/extensionEnablementWorkspaceTrustTransitionParticipant.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55

6+
import { localize } from 'vs/nls';
67
import { Disposable } from 'vs/base/common/lifecycle';
78
import { IWorkspaceTrustEnablementService, IWorkspaceTrustManagementService, IWorkspaceTrustTransitionParticipant } from 'vs/platform/workspace/common/workspaceTrust';
89
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
@@ -38,9 +39,11 @@ export class ExtensionEnablementWorkspaceTrustTransitionParticipant extends Disp
3839
if (environmentService.remoteAuthority) {
3940
hostService.reload();
4041
} else {
41-
extensionService.stopExtensionHosts(true); // TODO@lszomoru adopt support for extension host to veto stopping
42+
const stopped = await extensionService.stopExtensionHosts(localize('restartExtensionHost.reason', "Restarting extension host due to workspace trust change."));
4243
await extensionEnablementService.updateExtensionsEnablementsWhenWorkspaceTrustChanges();
43-
extensionService.startExtensionHosts();
44+
if (stopped) {
45+
extensionService.startExtensionHosts();
46+
}
4447
}
4548
}
4649
}

src/vs/workbench/contrib/notebook/common/notebookEditorModel.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@ import { Schemas } from 'vs/base/common/network';
1212
import { filter } from 'vs/base/common/objects';
1313
import { assertType } from 'vs/base/common/types';
1414
import { URI } from 'vs/base/common/uri';
15+
import { localize } from 'vs/nls';
1516
import { IRevertOptions, ISaveOptions, IUntypedEditorInput } from 'vs/workbench/common/editor';
1617
import { EditorModel } from 'vs/workbench/common/editor/editorModel';
1718
import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel';
1819
import { ICellDto2, INotebookEditorModel, INotebookLoadOptions, IResolvedNotebookEditorModel, NotebookCellsChangeType, NotebookData } from 'vs/workbench/contrib/notebook/common/notebookCommon';
1920
import { INotebookSerializer, INotebookService, SimpleNotebookProviderInfo } from 'vs/workbench/contrib/notebook/common/notebookService';
21+
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
2022
import { IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService';
2123
import { ILifecycleService } from 'vs/workbench/services/lifecycle/common/lifecycle';
2224
import { IFileWorkingCopyManager } from 'vs/workbench/services/workingCopy/common/fileWorkingCopyManager';
@@ -47,13 +49,29 @@ export class SimpleNotebookEditorModel extends EditorModel implements INotebookE
4749
readonly viewType: string,
4850
private readonly _workingCopyManager: IFileWorkingCopyManager<NotebookFileWorkingCopyModel, NotebookFileWorkingCopyModel>,
4951
@ILifecycleService lifecycleService: ILifecycleService,
50-
@IFilesConfigurationService private readonly _filesConfigurationService: IFilesConfigurationService
52+
@IFilesConfigurationService private readonly _filesConfigurationService: IFilesConfigurationService,
53+
@IExtensionService extensionService: IExtensionService
5154
) {
5255
super();
5356

5457
if (this.viewType === 'interactive') {
5558
lifecycleService.onBeforeShutdown(async e => e.veto(this.onBeforeShutdown(), 'veto.InteractiveWindow'));
5659
}
60+
61+
this._register(extensionService.onWillStop(e => {
62+
if (!this.isDirty()) {
63+
return;
64+
}
65+
66+
e.veto((async () => {
67+
const didSave = await this._workingCopy?.save();
68+
if (!didSave) {
69+
// Veto
70+
return true;
71+
}
72+
return false; // Don't veto
73+
})(), localize('vetoExtHostRestart', "Notebook could not be saved."));
74+
}));
5775
}
5876

5977
private async onBeforeShutdown() {

src/vs/workbench/contrib/relauncher/browser/relauncher.contribution.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ export class WorkspaceChangeExtHostRelauncher extends Disposable implements IWor
204204
if (environmentService.remoteAuthority) {
205205
hostService.reload(); // TODO@aeschli, workaround
206206
} else if (isNative) {
207-
const stopped = await extensionService.stopExtensionHosts(localize('restartExtensionHost.reason', "Restart Extension Host."));
207+
const stopped = await extensionService.stopExtensionHosts(localize('restartExtensionHost.reason', "Restarting extension host due to a workspace folder change."));
208208
if (stopped) {
209209
extensionService.startExtensionHosts();
210210
}

src/vs/workbench/services/extensions/common/abstractExtensionService.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -623,14 +623,8 @@ export abstract class AbstractExtensionService extends Disposable implements IEx
623623

624624
//#region Stopping / Starting / Restarting
625625

626-
public stopExtensionHosts(reason: string): Promise<boolean>;
627-
public stopExtensionHosts(force: true): void;
628-
public stopExtensionHosts(arg0: true | string): void | Promise<boolean> {
629-
if (arg0 === true) {
630-
return this._doStopExtensionHosts();
631-
}
632-
633-
return this._doStopExtensionHostsWithVeto(arg0);
626+
public stopExtensionHosts(reason: string): Promise<boolean> {
627+
return this._doStopExtensionHostsWithVeto(reason);
634628
}
635629

636630
protected _doStopExtensionHosts(): void {

src/vs/workbench/services/extensions/common/extensions.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -460,11 +460,6 @@ export interface IExtensionService {
460460
*/
461461
stopExtensionHosts(reason: string): Promise<boolean>;
462462

463-
/**
464-
* @deprecated Use `stopExtensionHosts()` instead.
465-
*/
466-
stopExtensionHosts(force: true): void;
467-
468463
/**
469464
* Starts the extension hosts.
470465
*/

src/vs/workbench/services/extensions/electron-sandbox/nativeExtensionService.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -723,7 +723,7 @@ class RestartExtensionHostAction extends Action2 {
723723
async run(accessor: ServicesAccessor): Promise<void> {
724724
const extensionService = accessor.get(IExtensionService);
725725

726-
const stopped = await extensionService.stopExtensionHosts(nls.localize('restartExtensionHost.reason', "Restart Extension Host."));
726+
const stopped = await extensionService.stopExtensionHosts(nls.localize('restartExtensionHost.reason', "Restarting extension host on explicit request."));
727727
if (stopped) {
728728
extensionService.startExtensionHosts();
729729
}

src/vs/workbench/services/extensions/test/browser/extensionService.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -256,13 +256,13 @@ suite('ExtensionService', () => {
256256

257257
test('issue #152204: Remote extension host not disposed after closing vscode client', async () => {
258258
await extService.startExtensionHosts();
259-
extService.stopExtensionHosts(true);
259+
await extService.stopExtensionHosts('foo');
260260
assert.deepStrictEqual(extService.order, (['create 1', 'create 2', 'create 3', 'dispose 3', 'dispose 2', 'dispose 1']));
261261
});
262262

263263
test('Extension host disposed when awaited', async () => {
264264
await extService.startExtensionHosts();
265-
await extService.stopExtensionHosts(`foo`);
265+
await extService.stopExtensionHosts('foo');
266266
assert.deepStrictEqual(extService.order, (['create 1', 'create 2', 'create 3', 'dispose 3', 'dispose 2', 'dispose 1']));
267267
});
268268

@@ -272,7 +272,7 @@ suite('ExtensionService', () => {
272272
extService.onWillStop(e => e.veto(true, 'test 1'));
273273
extService.onWillStop(e => e.veto(false, 'test 2'));
274274

275-
await extService.stopExtensionHosts(`foo`);
275+
await extService.stopExtensionHosts('foo');
276276
assert.deepStrictEqual(extService.order, (['create 1', 'create 2', 'create 3']));
277277
});
278278

@@ -283,7 +283,7 @@ suite('ExtensionService', () => {
283283
extService.onWillStop(e => e.veto(Promise.resolve(true), 'test 2'));
284284
extService.onWillStop(e => e.veto(Promise.resolve(false), 'test 3'));
285285

286-
await extService.stopExtensionHosts(`foo`);
286+
await extService.stopExtensionHosts('foo');
287287
assert.deepStrictEqual(extService.order, (['create 1', 'create 2', 'create 3']));
288288
});
289289
});

src/vs/workbench/services/userDataProfile/browser/userDataProfileManagement.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ export class UserDataProfileManagementService extends Disposable implements IUse
118118
const isRemoteWindow = !!this.environmentService.remoteAuthority;
119119

120120
if (!isRemoteWindow) {
121-
if (!(await this.extensionService.stopExtensionHosts(localize('switch profile', "Switching Profile")))) {
121+
if (!(await this.extensionService.stopExtensionHosts(localize('switch profile', "Switching to a profile.")))) {
122122
throw new CancellationError();
123123
}
124124
}

0 commit comments

Comments
 (0)