@@ -18,8 +18,7 @@ import { ParseError, parse } from 'vs/base/common/json';
1818import { FormattingOptions } from 'vs/base/common/jsonFormatter' ;
1919import { IStringDictionary } from 'vs/base/common/collections' ;
2020import { 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
2423type 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 {
0 commit comments