Skip to content

Commit 292dc61

Browse files
authored
Make edit session operations cancellable (microsoft#166764)
* Make edit session operations cancellable * Update test
1 parent 735e61b commit 292dc61

File tree

4 files changed

+34
-17
lines changed

4 files changed

+34
-17
lines changed

src/vs/platform/workspace/common/editSessions.ts

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

6-
import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation';
6+
import { CancellationToken } from 'vs/base/common/cancellation';
77
import { IDisposable } from 'vs/base/common/lifecycle';
88
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
99
import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
@@ -20,8 +20,8 @@ export interface IEditSessionIdentityService {
2020
readonly _serviceBrand: undefined;
2121

2222
registerEditSessionIdentityProvider(provider: IEditSessionIdentityProvider): IDisposable;
23-
getEditSessionIdentifier(workspaceFolder: IWorkspaceFolder, cancellationTokenSource: CancellationTokenSource): Promise<string | undefined>;
24-
provideEditSessionIdentityMatch(workspaceFolder: IWorkspaceFolder, identity1: string, identity2: string, cancellationTokenSource: CancellationTokenSource): Promise<EditSessionIdentityMatch | undefined>;
23+
getEditSessionIdentifier(workspaceFolder: IWorkspaceFolder, cancellationToken: CancellationToken): Promise<string | undefined>;
24+
provideEditSessionIdentityMatch(workspaceFolder: IWorkspaceFolder, identity1: string, identity2: string, cancellationToken: CancellationToken): Promise<EditSessionIdentityMatch | undefined>;
2525
}
2626

2727
export enum EditSessionIdentityMatch {

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

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ import { EditSessionsDataViews } from 'vs/workbench/contrib/editSessions/browser
4747
import { EditSessionsFileSystemProvider } from 'vs/workbench/contrib/editSessions/browser/editSessionsFileSystemProvider';
4848
import { isNative } from 'vs/base/common/platform';
4949
import { WorkspaceFolderCountContext } from 'vs/workbench/common/contextkeys';
50-
import { CancellationTokenSource } from 'vs/base/common/cancellation';
50+
import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation';
5151
import { equals } from 'vs/base/common/objects';
5252
import { EditSessionIdentityMatch, IEditSessionIdentityService } from 'vs/platform/workspace/common/editSessions';
5353
import { ThemeIcon } from 'vs/platform/theme/common/themeService';
@@ -209,11 +209,15 @@ export class EditSessionsContribution extends Disposable implements IWorkbenchCo
209209

210210
private async autoStoreEditSession() {
211211
if (this.configurationService.getValue('workbench.experimental.editSessions.autoStore') === 'onShutdown') {
212+
const cancellationTokenSource = new CancellationTokenSource();
212213
await this.progressService.withProgress({
213214
location: ProgressLocation.Window,
214215
type: 'syncing',
215216
title: localize('store working changes', 'Storing working changes...')
216-
}, async () => this.storeEditSession(false));
217+
}, async () => this.storeEditSession(false, cancellationTokenSource.token), () => {
218+
cancellationTokenSource.cancel();
219+
cancellationTokenSource.dispose();
220+
});
217221
}
218222
}
219223

@@ -308,11 +312,16 @@ export class EditSessionsContribution extends Disposable implements IWorkbenchCo
308312
// Run the store action to get back a ref
309313
let ref: string | undefined;
310314
if (shouldStoreEditSession) {
315+
const cancellationTokenSource = new CancellationTokenSource();
311316
ref = await that.progressService.withProgress({
312317
location: ProgressLocation.Notification,
318+
cancellable: true,
313319
type: 'syncing',
314320
title: localize('store your working changes', 'Storing your working changes...')
315-
}, async () => that.storeEditSession(false));
321+
}, async () => that.storeEditSession(false, cancellationTokenSource.token), () => {
322+
cancellationTokenSource.cancel();
323+
cancellationTokenSource.dispose();
324+
});
316325
}
317326

318327
// Append the ref to the URI
@@ -380,6 +389,7 @@ export class EditSessionsContribution extends Disposable implements IWorkbenchCo
380389
}
381390

382391
async run(accessor: ServicesAccessor): Promise<void> {
392+
const cancellationTokenSource = new CancellationTokenSource();
383393
await that.progressService.withProgress({
384394
location: ProgressLocation.Notification,
385395
title: localize('storing working changes', 'Storing working changes...')
@@ -390,7 +400,10 @@ export class EditSessionsContribution extends Disposable implements IWorkbenchCo
390400
};
391401
that.telemetryService.publicLog2<StoreEvent, StoreClassification>('editSessions.store');
392402

393-
await that.storeEditSession(true);
403+
await that.storeEditSession(true, cancellationTokenSource.token);
404+
}, () => {
405+
cancellationTokenSource.cancel();
406+
cancellationTokenSource.dispose();
394407
});
395408
}
396409
}));
@@ -484,7 +497,7 @@ export class EditSessionsContribution extends Disposable implements IWorkbenchCo
484497
if (folder.canonicalIdentity) {
485498
// Look for an edit session identifier that we can use
486499
for (const f of workspaceFolders) {
487-
const identity = await this.editSessionIdentityService.getEditSessionIdentifier(f, cancellationTokenSource);
500+
const identity = await this.editSessionIdentityService.getEditSessionIdentifier(f, cancellationTokenSource.token);
488501
this.logService.info(`Matching identity ${identity} against edit session folder identity ${folder.canonicalIdentity}...`);
489502

490503
if (equals(identity, folder.canonicalIdentity)) {
@@ -493,7 +506,7 @@ export class EditSessionsContribution extends Disposable implements IWorkbenchCo
493506
}
494507

495508
if (identity !== undefined) {
496-
const match = await this.editSessionIdentityService.provideEditSessionIdentityMatch(f, identity, folder.canonicalIdentity, cancellationTokenSource);
509+
const match = await this.editSessionIdentityService.provideEditSessionIdentityMatch(f, identity, folder.canonicalIdentity, cancellationTokenSource.token);
497510
if (match === EditSessionIdentityMatch.Complete) {
498511
folderRoot = f;
499512
break;
@@ -566,7 +579,7 @@ export class EditSessionsContribution extends Disposable implements IWorkbenchCo
566579
}
567580
}
568581

569-
async storeEditSession(fromStoreCommand: boolean): Promise<string | undefined> {
582+
async storeEditSession(fromStoreCommand: boolean, cancellationToken: CancellationToken): Promise<string | undefined> {
570583
const folders: Folder[] = [];
571584
let hasEdits = false;
572585

@@ -612,7 +625,10 @@ export class EditSessionsContribution extends Disposable implements IWorkbenchCo
612625
}
613626
}
614627

615-
const canonicalIdentity = workspaceFolder ? await this.editSessionIdentityService.getEditSessionIdentifier(workspaceFolder, new CancellationTokenSource()) : undefined;
628+
let canonicalIdentity = undefined;
629+
if (workspaceFolder !== null && workspaceFolder !== undefined) {
630+
canonicalIdentity = await this.editSessionIdentityService.getEditSessionIdentifier(workspaceFolder, cancellationToken);
631+
}
616632

617633
folders.push({ workingChanges, name: name ?? '', canonicalIdentity: canonicalIdentity ?? undefined });
618634
}

src/vs/workbench/contrib/editSessions/test/browser/editSessions.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import { ITextModelService } from 'vs/editor/common/services/resolverService';
3737
import { ILifecycleService } from 'vs/workbench/services/lifecycle/common/lifecycle';
3838
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
3939
import { IEditorService, ISaveAllEditorsOptions } from 'vs/workbench/services/editor/common/editorService';
40+
import { CancellationTokenSource } from 'vs/base/common/cancellation';
4041

4142
const folderName = 'test-folder';
4243
const folderUri = URI.file(`/${folderName}`);
@@ -168,7 +169,7 @@ suite('Edit session sync', () => {
168169
// Create root folder
169170
await fileService.createFolder(folderUri);
170171

171-
await editSessionsContribution.storeEditSession(true);
172+
await editSessionsContribution.storeEditSession(true, new CancellationTokenSource().token);
172173

173174
// Verify that we did not attempt to write the edit session
174175
assert.equal(writeStub.called, false);

src/vs/workbench/services/workspaces/common/editSessionIdentityService.ts

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

6-
import { CancellationTokenSource } from 'vs/base/common/cancellation';
6+
import { CancellationToken } from 'vs/base/common/cancellation';
77
import { IDisposable, toDisposable } from 'vs/base/common/lifecycle';
88
import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions';
99
import { ILogService } from 'vs/platform/log/common/log';
@@ -32,22 +32,22 @@ export class EditSessionIdentityService implements IEditSessionIdentityService {
3232
});
3333
}
3434

35-
async getEditSessionIdentifier(workspaceFolder: IWorkspaceFolder, cancellationTokenSource: CancellationTokenSource): Promise<string | undefined> {
35+
async getEditSessionIdentifier(workspaceFolder: IWorkspaceFolder, token: CancellationToken): Promise<string | undefined> {
3636
const { scheme } = workspaceFolder.uri;
3737

3838
const provider = await this.activateProvider(scheme);
3939
this._logService.trace(`EditSessionIdentityProvider for scheme ${scheme} available: ${!!provider}`);
4040

41-
return provider?.getEditSessionIdentifier(workspaceFolder, cancellationTokenSource.token);
41+
return provider?.getEditSessionIdentifier(workspaceFolder, token);
4242
}
4343

44-
async provideEditSessionIdentityMatch(workspaceFolder: IWorkspaceFolder, identity1: string, identity2: string, cancellationTokenSource: CancellationTokenSource): Promise<EditSessionIdentityMatch | undefined> {
44+
async provideEditSessionIdentityMatch(workspaceFolder: IWorkspaceFolder, identity1: string, identity2: string, cancellationToken: CancellationToken): Promise<EditSessionIdentityMatch | undefined> {
4545
const { scheme } = workspaceFolder.uri;
4646

4747
const provider = await this.activateProvider(scheme);
4848
this._logService.trace(`EditSessionIdentityProvider for scheme ${scheme} available: ${!!provider}`);
4949

50-
return provider?.provideEditSessionIdentityMatch?.(workspaceFolder, identity1, identity2, cancellationTokenSource.token);
50+
return provider?.provideEditSessionIdentityMatch?.(workspaceFolder, identity1, identity2, cancellationToken);
5151
}
5252

5353
private async activateProvider(scheme: string) {

0 commit comments

Comments
 (0)