mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-11 18:48:33 -05:00
Merge from vscode 52dcb723a39ae75bee1bd56b3312d7fcdc87aeed (#6719)
This commit is contained in:
@@ -106,20 +106,15 @@ export class BackupFilesModel implements IBackupFilesModel {
|
||||
|
||||
export class BackupFileService implements IBackupFileService {
|
||||
|
||||
_serviceBrand: ServiceIdentifier<IBackupFileService>;
|
||||
_serviceBrand!: ServiceIdentifier<IBackupFileService>;
|
||||
|
||||
private impl: IBackupFileService;
|
||||
|
||||
constructor(
|
||||
@IWorkbenchEnvironmentService environmentService: IWorkbenchEnvironmentService,
|
||||
@IFileService fileService: IFileService
|
||||
@IWorkbenchEnvironmentService private environmentService: IWorkbenchEnvironmentService,
|
||||
@IFileService protected fileService: IFileService
|
||||
) {
|
||||
const backupWorkspaceResource = environmentService.configuration.backupWorkspaceResource;
|
||||
if (backupWorkspaceResource) {
|
||||
this.impl = new BackupFileServiceImpl(backupWorkspaceResource, this.hashPath, fileService);
|
||||
} else {
|
||||
this.impl = new InMemoryBackupFileService(this.hashPath);
|
||||
}
|
||||
this.initialize();
|
||||
}
|
||||
|
||||
protected hashPath(resource: URI): string {
|
||||
@@ -128,9 +123,25 @@ export class BackupFileService implements IBackupFileService {
|
||||
return hash(str).toString(16);
|
||||
}
|
||||
|
||||
initialize(backupWorkspaceResource: URI): void {
|
||||
private initialize(): void {
|
||||
const backupWorkspaceResource = this.environmentService.configuration.backupWorkspaceResource;
|
||||
if (backupWorkspaceResource) {
|
||||
this.impl = new BackupFileServiceImpl(backupWorkspaceResource, this.hashPath, this.fileService);
|
||||
} else {
|
||||
this.impl = new InMemoryBackupFileService(this.hashPath);
|
||||
}
|
||||
}
|
||||
|
||||
reinitialize(): void {
|
||||
|
||||
// Re-init implementation (unless we are running in-memory)
|
||||
if (this.impl instanceof BackupFileServiceImpl) {
|
||||
this.impl.initialize(backupWorkspaceResource);
|
||||
const backupWorkspaceResource = this.environmentService.configuration.backupWorkspaceResource;
|
||||
if (backupWorkspaceResource) {
|
||||
this.impl.initialize(backupWorkspaceResource);
|
||||
} else {
|
||||
this.impl = new InMemoryBackupFileService(this.hashPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,15 +188,15 @@ class BackupFileServiceImpl implements IBackupFileService {
|
||||
private static readonly PREAMBLE_META_SEPARATOR = ' '; // using a character that is know to be escaped in a URI as separator
|
||||
private static readonly PREAMBLE_MAX_LENGTH = 10000;
|
||||
|
||||
_serviceBrand: ServiceIdentifier<IBackupFileService>;
|
||||
_serviceBrand!: ServiceIdentifier<IBackupFileService>;
|
||||
|
||||
private backupWorkspacePath: URI;
|
||||
private backupWorkspacePath!: URI;
|
||||
|
||||
private isShuttingDown: boolean;
|
||||
private ioOperationQueues: ResourceQueue; // queue IO operations to ensure write order
|
||||
|
||||
private ready: Promise<IBackupFilesModel>;
|
||||
private model: IBackupFilesModel;
|
||||
private ready!: Promise<IBackupFilesModel>;
|
||||
private model!: IBackupFilesModel;
|
||||
|
||||
constructor(
|
||||
backupWorkspaceResource: URI,
|
||||
@@ -201,10 +212,10 @@ class BackupFileServiceImpl implements IBackupFileService {
|
||||
initialize(backupWorkspaceResource: URI): void {
|
||||
this.backupWorkspacePath = backupWorkspaceResource;
|
||||
|
||||
this.ready = this.init();
|
||||
this.ready = this.doInitialize();
|
||||
}
|
||||
|
||||
private init(): Promise<IBackupFilesModel> {
|
||||
private doInitialize(): Promise<IBackupFilesModel> {
|
||||
this.model = new BackupFilesModel(this.fileService);
|
||||
|
||||
return this.model.resolve(this.backupWorkspacePath);
|
||||
@@ -323,7 +334,7 @@ class BackupFileServiceImpl implements IBackupFileService {
|
||||
return contents.substr(0, newLineIndex);
|
||||
}
|
||||
|
||||
throw new Error(`Could not find ${JSON.stringify(matchingString)} in first ${maximumBytesToRead} bytes of ${file}`);
|
||||
throw new Error(`Backup: Could not find ${JSON.stringify(matchingString)} in first ${maximumBytesToRead} bytes of ${file}`);
|
||||
}
|
||||
|
||||
async resolveBackupContent<T extends object>(backup: URI): Promise<IResolvedBackup<T>> {
|
||||
@@ -357,9 +368,7 @@ class BackupFileServiceImpl implements IBackupFileService {
|
||||
const content = await this.fileService.readFileStream(backup);
|
||||
const factory = await createTextBufferFactoryFromStream(content.value, metaPreambleFilter);
|
||||
|
||||
// Trigger read for meta data extraction from the filter above
|
||||
factory.getFirstLineText(1);
|
||||
|
||||
// Extract meta data (if any)
|
||||
let meta: T | undefined;
|
||||
const metaStartIndex = metaRaw.indexOf(BackupFileServiceImpl.PREAMBLE_META_SEPARATOR);
|
||||
if (metaStartIndex !== -1) {
|
||||
@@ -370,6 +379,15 @@ class BackupFileServiceImpl implements IBackupFileService {
|
||||
}
|
||||
}
|
||||
|
||||
// We have seen reports (e.g. https://github.com/microsoft/vscode/issues/78500) where
|
||||
// if VSCode goes down while writing the backup file, the file can turn empty because
|
||||
// it always first gets truncated and then written to. In this case, we will not find
|
||||
// the meta-end marker ('\n') and as such the backup can only be invalid. We bail out
|
||||
// here if that is the case.
|
||||
if (!metaEndFound) {
|
||||
throw new Error(`Backup: Could not find meta end marker in ${backup}. The file is probably corrupt.`);
|
||||
}
|
||||
|
||||
return { value: factory, meta };
|
||||
}
|
||||
|
||||
@@ -380,7 +398,7 @@ class BackupFileServiceImpl implements IBackupFileService {
|
||||
|
||||
export class InMemoryBackupFileService implements IBackupFileService {
|
||||
|
||||
_serviceBrand: ServiceIdentifier<IBackupFileService>;
|
||||
_serviceBrand!: ServiceIdentifier<IBackupFileService>;
|
||||
|
||||
private backups: Map<string, ITextSnapshot> = new Map();
|
||||
|
||||
@@ -440,4 +458,4 @@ export class InMemoryBackupFileService implements IBackupFileService {
|
||||
toBackupResource(resource: URI): URI {
|
||||
return URI.file(join(resource.scheme, this.hashPath(resource)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user