提交 52c8af5a 编写于 作者: D Daniel Imms

Perform a last minute backup when closing the last window

上级 e4f0dec7
......@@ -193,10 +193,18 @@ export class UntitledEditorModel extends StringEditorModel implements IEncodingS
this.fileService.discardBackup(this.resource);
}
private doBackup(): TPromise<void> {
public backup(): TPromise<void> {
return this.doBackup(true);
}
private doBackup(immediate?: boolean): TPromise<void> {
// Cancel any currently running backups to make this the one that succeeds
this.cancelBackupPromises();
if (immediate) {
return this.fileService.backupFile(this.resource, this.getValue()).then(f => void 0);
}
// Create new backup promise and keep it
const promise = TPromise.timeout(1000).then(() => {
this.fileService.backupFile(this.resource, this.getValue()); // Very important here to not return the promise because if the timeout promise is canceled it will bubble up the error otherwise - do not change
......
......@@ -458,6 +458,7 @@ export class FileService implements IFileService {
}
public backupFile(resource: uri, content: string): TPromise<IFileStat> {
// TODO: This should not backup unless necessary. Currently this is called for each file on close to ensure the files are backed up.
if (resource.scheme === 'file') {
this.backupService.registerBackupFile(resource);
}
......
......@@ -119,14 +119,12 @@ export abstract class TextFileService implements ITextFileService {
// If hot exit is enabled then save the dirty files in the workspace and then exit
if (this.configuredHotExit) {
// TODO: Check if dirty
// TODO: Do a last minute backup if required
// TODO: There may be a better way of verifying that only a single window is open?
// Only remove the workspace from the backup service if it's not the last one or it's not dirty
if (this.backupService.getBackupWorkspaces().length > 1 || this.getDirty().length === 0) {
this.backupService.removeWorkspace(this.contextService.getWorkspace().resource.fsPath);
} else {
return false; // the backup will be restored, no veto
// TODO: Better error handling here? Perhaps present confirm if there was an error?
return this.backupAll().then(() => false); // the backup will be restored, no veto
}
}
......@@ -384,6 +382,54 @@ export abstract class TextFileService implements ITextFileService {
});
}
/**
* Performs an immedate backup of all dirty file and untitled models.
*/
private backupAll(): TPromise<void> {
const toBackup = this.getDirty();
// split up between files and untitled
const filesToBackup: URI[] = [];
const untitledToBackup: URI[] = [];
toBackup.forEach(s => {
if (s.scheme === 'file') {
filesToBackup.push(s);
} else if (s.scheme === 'untitled') {
untitledToBackup.push(s);
}
});
return this.doBackupAll(filesToBackup, untitledToBackup);
}
private doBackupAll(fileResources: URI[], untitledResources: URI[]): TPromise<void> {
// Handle file resources first
const dirtyFileModels = this.getDirtyFileModels(fileResources);
const mapResourceToResult: { [resource: string]: IResult } = Object.create(null);
dirtyFileModels.forEach(m => {
mapResourceToResult[m.getResource().toString()] = {
source: m.getResource()
};
});
return TPromise.join(dirtyFileModels.map(model => {
return model.backup().then(() => {
mapResourceToResult[model.getResource().toString()].success = true;
});
})).then(result => {
// Handle untitled resources
const untitledModelPromises = untitledResources.map(untitledResource => this.untitledEditorService.get(untitledResource))
.filter(untitled => !!untitled)
.map(untitled => untitled.resolve());
return TPromise.join(untitledModelPromises).then(untitledModels => {
const untitledBackupPromises = untitledModels.map(model => model.backup());
return TPromise.join(untitledBackupPromises).then(() => void 0);
});
});
}
private getFileModels(resources?: URI[]): ITextFileEditorModel[];
private getFileModels(resource?: URI): ITextFileEditorModel[];
private getFileModels(arg1?: any): ITextFileEditorModel[] {
......
......@@ -412,10 +412,22 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
}
}
private doBackup(): TPromise<void> {
public backup(): TPromise<void> {
if (!this.dirty) {
return TPromise.as<void>(null);
}
return this.doBackup(true);
}
private doBackup(immediate?: boolean): TPromise<void> {
// Cancel any currently running backups to make this the one that succeeds
this.cancelBackupPromises();
if (immediate) {
return this.fileService.backupFile(this.resource, this.getValue()).then(f => void 0);
}
// Create new backup promise and keep it
const promise = TPromise.timeout(1000).then(() => {
this.fileService.backupFile(this.resource, this.getValue()); // Very important here to not return the promise because if the timeout promise is canceled it will bubble up the error otherwise - do not change
......
......@@ -217,6 +217,8 @@ export interface ITextFileEditorModel extends ITextEditorModel, IEncodingSupport
save(options?: IModelSaveOptions): TPromise<void>;
backup(): TPromise<void>;
setRestoreResource(resource: URI): void;
revert(): TPromise<void>;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册