提交 72950f8b 编写于 作者: B Benjamin Pasero

backup - wire in cancellation token to implementation

上级 29d459b6
......@@ -128,7 +128,7 @@ export abstract class BackupTracker extends Disposable {
if (workingCopy.isDirty()) {
this.logService.trace(`[backup tracker] storing backup`, workingCopy.resource.toString());
await this.backupFileService.backup(workingCopy.resource, backup.content, this.getContentVersion(workingCopy), backup.meta);
await this.backupFileService.backup(workingCopy.resource, backup.content, this.getContentVersion(workingCopy), backup.meta, cts.token);
}
} catch (error) {
this.logService.error(error);
......
......@@ -6,6 +6,7 @@
import { URI } from 'vs/base/common/uri';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { ITextBufferFactory, ITextSnapshot } from 'vs/editor/common/model';
import { CancellationToken } from 'vs/base/common/cancellation';
export const IBackupFileService = createDecorator<IBackupFileService>('backupFileService');
......@@ -59,8 +60,9 @@ export interface IBackupFileService {
* @param versionId The optionsl version id of the resource to backup.
* @param meta The optional meta data of the resource to backup. This information
* can be restored later when loading the backup again.
* @param token The optional cancellation token if the operation can be cancelled.
*/
backup<T extends object>(resource: URI, content?: ITextSnapshot, versionId?: number, meta?: T): Promise<void>;
backup<T extends object>(resource: URI, content?: ITextSnapshot, versionId?: number, meta?: T, token?: CancellationToken): Promise<void>;
/**
* Discards the backup associated with a resource if it exists.
......
......@@ -21,6 +21,7 @@ import { VSBuffer } from 'vs/base/common/buffer';
import { TextSnapshotReadable, stringToSnapshot } from 'vs/workbench/services/textfile/common/textfiles';
import { Disposable } from 'vs/base/common/lifecycle';
import { ILogService } from 'vs/platform/log/common/log';
import { CancellationToken } from 'vs/base/common/cancellation';
export interface IBackupFilesModel {
resolve(backupRoot: URI): Promise<IBackupFilesModel>;
......@@ -157,8 +158,8 @@ export class BackupFileService implements IBackupFileService {
return this.impl.hasBackupSync(resource, versionId);
}
backup<T extends object>(resource: URI, content?: ITextSnapshot, versionId?: number, meta?: T): Promise<void> {
return this.impl.backup(resource, content, versionId, meta);
backup<T extends object>(resource: URI, content?: ITextSnapshot, versionId?: number, meta?: T, token?: CancellationToken): Promise<void> {
return this.impl.backup(resource, content, versionId, meta, token);
}
discardBackup(resource: URI): Promise<void> {
......@@ -232,8 +233,11 @@ class BackupFileServiceImpl extends Disposable implements IBackupFileService {
return this.model.has(backupResource, versionId);
}
async backup<T extends object>(resource: URI, content?: ITextSnapshot, versionId?: number, meta?: T): Promise<void> {
async backup<T extends object>(resource: URI, content?: ITextSnapshot, versionId?: number, meta?: T, token?: CancellationToken): Promise<void> {
const model = await this.ready;
if (token?.isCancellationRequested) {
return;
}
const backupResource = this.toBackupResource(resource);
if (model.has(backupResource, versionId, meta)) {
......@@ -241,6 +245,10 @@ class BackupFileServiceImpl extends Disposable implements IBackupFileService {
}
return this.ioOperationQueues.queueFor(backupResource).queue(async () => {
if (token?.isCancellationRequested) {
return;
}
let preamble: string | undefined = undefined;
// With Metadata: URI + META-START + Meta + END
......@@ -419,7 +427,7 @@ export class InMemoryBackupFileService implements IBackupFileService {
return this.backups.has(backupResource.toString());
}
async backup<T extends object>(resource: URI, content?: ITextSnapshot, versionId?: number, meta?: T): Promise<void> {
async backup<T extends object>(resource: URI, content?: ITextSnapshot, versionId?: number, meta?: T, token?: CancellationToken): Promise<void> {
const backupResource = this.toBackupResource(resource);
this.backups.set(backupResource.toString(), content || stringToSnapshot(''));
}
......
......@@ -28,6 +28,7 @@ import { FileUserDataProvider } from 'vs/workbench/services/userData/common/file
import { VSBuffer } from 'vs/base/common/buffer';
import { TestWorkbenchConfiguration } from 'vs/workbench/test/electron-browser/workbenchTestServices';
import { TestProductService } from 'vs/workbench/test/browser/workbenchTestServices';
import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation';
const userdataDir = getRandomTestPath(os.tmpdir(), 'vsctests', 'backupfileservice');
const backupHome = path.join(userdataDir, 'Backups');
......@@ -80,8 +81,8 @@ export class NodeTestBackupFileService extends BackupFileService {
return new Promise(resolve => this.backupResourceJoiners.push(resolve));
}
async backup(resource: URI, content?: ITextSnapshot, versionId?: number, meta?: any): Promise<void> {
await super.backup(resource, content, versionId, meta);
async backup(resource: URI, content?: ITextSnapshot, versionId?: number, meta?: any, token?: CancellationToken): Promise<void> {
await super.backup(resource, content, versionId, meta, token);
while (this.backupResourceJoiners.length) {
this.backupResourceJoiners.pop()!();
......@@ -262,6 +263,16 @@ suite('BackupFileService', () => {
model.dispose();
});
test('cancellation', async () => {
const cts = new CancellationTokenSource();
const promise = service.backup(fooFile, undefined, undefined, undefined, cts.token);
cts.cancel();
await promise;
assert.equal(fs.existsSync(fooBackupPath), false);
assert.ok(!service.hasBackupSync(fooFile));
});
});
suite('discardBackup', () => {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册