Skip to content

Commit c6d4c7e

Browse files
committed
improve backup
- retain atleast 10 entries - do not fail when writing to backup fails
1 parent 2c1ad8e commit c6d4c7e

5 files changed

Lines changed: 40 additions & 29 deletions

File tree

src/vs/platform/userDataSync/common/abstractSynchronizer.ts

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@ import { ParseError, parse } from 'vs/base/common/json';
1818
import { FormattingOptions } from 'vs/base/common/jsonFormatter';
1919
import { IStringDictionary } from 'vs/base/common/collections';
2020
import { localize } from 'vs/nls';
21-
22-
const BACK_UP_MAX_AGE = 1000 * 60 * 60 * 24 * 30; /* 30 days */
21+
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
2322

2423
type SyncSourceClassification = {
2524
source?: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true };
@@ -65,6 +64,7 @@ export abstract class AbstractSynchroniser extends Disposable {
6564
@IUserDataSyncEnablementService protected readonly userDataSyncEnablementService: IUserDataSyncEnablementService,
6665
@ITelemetryService private readonly telemetryService: ITelemetryService,
6766
@IUserDataSyncLogService protected readonly logService: IUserDataSyncLogService,
67+
@IConfigurationService protected readonly configurationService: IConfigurationService,
6868
) {
6969
super();
7070
this.syncFolder = joinPath(environmentService.userDataSyncHome, source);
@@ -191,31 +191,38 @@ export abstract class AbstractSynchroniser extends Disposable {
191191

192192
protected async backupLocal(content: VSBuffer): Promise<void> {
193193
const resource = joinPath(this.syncFolder, toLocalISOString(new Date()).replace(/-|:|\.\d+Z$/g, ''));
194-
await this.fileService.writeFile(resource, content);
194+
try {
195+
await this.fileService.writeFile(resource, content);
196+
} catch (e) {
197+
this.logService.error(e);
198+
}
195199
this.cleanUpDelayer.trigger(() => this.cleanUpBackup());
196200
}
197201

198202
private async cleanUpBackup(): Promise<void> {
199203
const stat = await this.fileService.resolve(this.syncFolder);
200204
if (stat.children) {
201-
const all = stat.children.filter(stat => stat.isFile && /^\d{8}T\d{6}$/.test(stat.name));
202-
if (all.length > 10) {
203-
const toDelete = all.filter(stat => {
204-
const ctime = stat.ctime || new Date(
205-
parseInt(stat.name.substring(0, 4)),
206-
parseInt(stat.name.substring(4, 6)) - 1,
207-
parseInt(stat.name.substring(6, 8)),
208-
parseInt(stat.name.substring(9, 11)),
209-
parseInt(stat.name.substring(11, 13)),
210-
parseInt(stat.name.substring(13, 15))
211-
).getTime();
212-
return Date.now() - ctime > BACK_UP_MAX_AGE;
213-
});
214-
await Promise.all(toDelete.map(stat => {
215-
this.logService.info('Deleting from backup', stat.resource.path);
216-
this.fileService.del(stat.resource);
217-
}));
205+
const all = stat.children.filter(stat => stat.isFile && /^\d{8}T\d{6}$/.test(stat.name)).sort();
206+
const backUpMaxAge = 1000 * 60 * 60 * 24 * (this.configurationService.getValue<number>('sync.localBackupDuration') || 30 /* Default 30 days */);
207+
let toDelete = all.filter(stat => {
208+
const ctime = stat.ctime || new Date(
209+
parseInt(stat.name.substring(0, 4)),
210+
parseInt(stat.name.substring(4, 6)) - 1,
211+
parseInt(stat.name.substring(6, 8)),
212+
parseInt(stat.name.substring(9, 11)),
213+
parseInt(stat.name.substring(11, 13)),
214+
parseInt(stat.name.substring(13, 15))
215+
).getTime();
216+
return Date.now() - ctime > backUpMaxAge;
217+
});
218+
const remaining = all.length - toDelete.length;
219+
if (remaining < 10) {
220+
toDelete = toDelete.slice(10 - remaining);
218221
}
222+
await Promise.all(toDelete.map(stat => {
223+
this.logService.info('Deleting from backup', stat.resource.path);
224+
this.fileService.del(stat.resource);
225+
}));
219226
}
220227
}
221228

@@ -247,8 +254,9 @@ export abstract class AbstractFileSynchroniser extends AbstractSynchroniser {
247254
@IUserDataSyncEnablementService userDataSyncEnablementService: IUserDataSyncEnablementService,
248255
@ITelemetryService telemetryService: ITelemetryService,
249256
@IUserDataSyncLogService logService: IUserDataSyncLogService,
257+
@IConfigurationService configurationService: IConfigurationService,
250258
) {
251-
super(source, fileService, environmentService, userDataSyncStoreService, userDataSyncEnablementService, telemetryService, logService);
259+
super(source, fileService, environmentService, userDataSyncStoreService, userDataSyncEnablementService, telemetryService, logService, configurationService);
252260
this._register(this.fileService.watch(dirname(file)));
253261
this._register(this.fileService.onDidFilesChange(e => this.onFileChanges(e)));
254262
}
@@ -346,8 +354,9 @@ export abstract class AbstractJsonFileSynchroniser extends AbstractFileSynchroni
346354
@ITelemetryService telemetryService: ITelemetryService,
347355
@IUserDataSyncLogService logService: IUserDataSyncLogService,
348356
@IUserDataSyncUtilService protected readonly userDataSyncUtilService: IUserDataSyncUtilService,
357+
@IConfigurationService configurationService: IConfigurationService,
349358
) {
350-
super(file, source, fileService, environmentService, userDataSyncStoreService, userDataSyncEnablementService, telemetryService, logService);
359+
super(file, source, fileService, environmentService, userDataSyncStoreService, userDataSyncEnablementService, telemetryService, logService, configurationService);
351360
}
352361

353362
protected hasErrors(content: string): boolean {

src/vs/platform/userDataSync/common/extensionsSync.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,11 @@ export class ExtensionsSynchroniser extends AbstractSynchroniser implements IUse
4646
@IGlobalExtensionEnablementService private readonly extensionEnablementService: IGlobalExtensionEnablementService,
4747
@IUserDataSyncLogService logService: IUserDataSyncLogService,
4848
@IExtensionGalleryService private readonly extensionGalleryService: IExtensionGalleryService,
49-
@IConfigurationService private readonly configurationService: IConfigurationService,
49+
@IConfigurationService configurationService: IConfigurationService,
5050
@IUserDataSyncEnablementService userDataSyncEnablementService: IUserDataSyncEnablementService,
5151
@ITelemetryService telemetryService: ITelemetryService,
5252
) {
53-
super(SyncSource.Extensions, fileService, environmentService, userDataSyncStoreService, userDataSyncEnablementService, telemetryService, logService);
53+
super(SyncSource.Extensions, fileService, environmentService, userDataSyncStoreService, userDataSyncEnablementService, telemetryService, logService, configurationService);
5454
this._register(
5555
Event.debounce(
5656
Event.any<any>(

src/vs/platform/userDataSync/common/globalStateSync.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { merge } from 'vs/platform/userDataSync/common/globalStateMerge';
1515
import { parse } from 'vs/base/common/json';
1616
import { AbstractSynchroniser, IRemoteUserData } from 'vs/platform/userDataSync/common/abstractSynchronizer';
1717
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
18+
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
1819

1920
const argvProperties: string[] = ['locale'];
2021

@@ -38,8 +39,9 @@ export class GlobalStateSynchroniser extends AbstractSynchroniser implements IUs
3839
@IEnvironmentService private readonly environmentService: IEnvironmentService,
3940
@IUserDataSyncEnablementService userDataSyncEnablementService: IUserDataSyncEnablementService,
4041
@ITelemetryService telemetryService: ITelemetryService,
42+
@IConfigurationService configurationService: IConfigurationService,
4143
) {
42-
super(SyncSource.GlobalState, fileService, environmentService, userDataSyncStoreService, userDataSyncEnablementService, telemetryService, logService);
44+
super(SyncSource.GlobalState, fileService, environmentService, userDataSyncStoreService, userDataSyncEnablementService, telemetryService, logService, configurationService);
4345
this._register(this.fileService.watch(dirname(this.environmentService.argvResource)));
4446
this._register(Event.filter(this.fileService.onDidFilesChange, e => e.contains(this.environmentService.argvResource))(() => this._onDidChangeLocal.fire()));
4547
}

src/vs/platform/userDataSync/common/keybindingsSync.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,14 @@ export class KeybindingsSynchroniser extends AbstractJsonFileSynchroniser implem
3636
constructor(
3737
@IUserDataSyncStoreService userDataSyncStoreService: IUserDataSyncStoreService,
3838
@IUserDataSyncLogService logService: IUserDataSyncLogService,
39-
@IConfigurationService private readonly configurationService: IConfigurationService,
39+
@IConfigurationService configurationService: IConfigurationService,
4040
@IUserDataSyncEnablementService userDataSyncEnablementService: IUserDataSyncEnablementService,
4141
@IFileService fileService: IFileService,
4242
@IEnvironmentService private readonly environmentService: IEnvironmentService,
4343
@IUserDataSyncUtilService userDataSyncUtilService: IUserDataSyncUtilService,
4444
@ITelemetryService telemetryService: ITelemetryService,
4545
) {
46-
super(environmentService.keybindingsResource, SyncSource.Keybindings, fileService, environmentService, userDataSyncStoreService, userDataSyncEnablementService, telemetryService, logService, userDataSyncUtilService);
46+
super(environmentService.keybindingsResource, SyncSource.Keybindings, fileService, environmentService, userDataSyncStoreService, userDataSyncEnablementService, telemetryService, logService, userDataSyncUtilService, configurationService);
4747
}
4848

4949
async pull(): Promise<void> {

src/vs/platform/userDataSync/common/settingsSync.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,11 @@ export class SettingsSynchroniser extends AbstractJsonFileSynchroniser implement
5151
@IUserDataSyncStoreService userDataSyncStoreService: IUserDataSyncStoreService,
5252
@IUserDataSyncLogService logService: IUserDataSyncLogService,
5353
@IUserDataSyncUtilService userDataSyncUtilService: IUserDataSyncUtilService,
54-
@IConfigurationService private readonly configurationService: IConfigurationService,
54+
@IConfigurationService configurationService: IConfigurationService,
5555
@IUserDataSyncEnablementService userDataSyncEnablementService: IUserDataSyncEnablementService,
5656
@ITelemetryService telemetryService: ITelemetryService,
5757
) {
58-
super(environmentService.settingsResource, SyncSource.Settings, fileService, environmentService, userDataSyncStoreService, userDataSyncEnablementService, telemetryService, logService, userDataSyncUtilService);
58+
super(environmentService.settingsResource, SyncSource.Settings, fileService, environmentService, userDataSyncStoreService, userDataSyncEnablementService, telemetryService, logService, userDataSyncUtilService, configurationService);
5959
}
6060

6161
protected setStatus(status: SyncStatus): void {

0 commit comments

Comments
 (0)