Merge from vscode e5834d3280fcd04898efeac32b9cf1b893f9b127 (#9385)

* Merge from vscode e5834d3280fcd04898efeac32b9cf1b893f9b127

* distro
This commit is contained in:
Anthony Dresser
2020-02-28 00:37:06 -08:00
committed by GitHub
parent 70851716f7
commit 5d13ebf0d2
143 changed files with 1711 additions and 934 deletions

View File

@@ -68,7 +68,7 @@ export abstract class AbstractSynchroniser extends Disposable {
) {
super();
this.syncFolder = joinPath(environmentService.userDataSyncHome, source);
this.lastSyncResource = joinPath(this.syncFolder, `.lastSync${source}.json`);
this.lastSyncResource = joinPath(this.syncFolder, `lastSync${source}.json`);
this.cleanUpDelayer = new ThrottledDelayer(50);
this.cleanUpBackup();
}
@@ -202,7 +202,7 @@ export abstract class AbstractSynchroniser extends Disposable {
}
protected async backupLocal(content: VSBuffer): Promise<void> {
const resource = joinPath(this.syncFolder, toLocalISOString(new Date()).replace(/-|:|\.\d+Z$/g, ''));
const resource = joinPath(this.syncFolder, `${toLocalISOString(new Date()).replace(/-|:|\.\d+Z$/g, '')}.json`);
try {
await this.fileService.writeFile(resource, content);
} catch (e) {
@@ -213,9 +213,13 @@ export abstract class AbstractSynchroniser extends Disposable {
private async cleanUpBackup(): Promise<void> {
try {
if (!(await this.fileService.exists(this.syncFolder))) {
return;
}
const stat = await this.fileService.resolve(this.syncFolder);
if (stat.children) {
const all = stat.children.filter(stat => stat.isFile && /^\d{8}T\d{6}$/.test(stat.name)).sort();
const all = stat.children.filter(stat => stat.isFile && /^\d{8}T\d{6}(\.json)?$/.test(stat.name)).sort();
console.log(all.map(a => a.name));
const backUpMaxAge = 1000 * 60 * 60 * 24 * (this.configurationService.getValue<number>('sync.localBackupDuration') || 30 /* Default 30 days */);
let toDelete = all.filter(stat => {
const ctime = stat.ctime || new Date(

View File

@@ -194,7 +194,7 @@ export class ExtensionsSynchroniser extends AbstractSynchroniser implements IUse
if (added.length || removed.length || updated.length) {
// back up all disabled or market place extensions
const backUpExtensions = localExtensions.filter(e => e.disabled || !!e.identifier.uuid);
await this.backupLocal(VSBuffer.fromString(JSON.stringify(backUpExtensions)));
await this.backupLocal(VSBuffer.fromString(JSON.stringify(backUpExtensions, null, '\t')));
skippedExtensions = await this.updateLocalExtensions(added, removed, updated, skippedExtensions);
}

View File

@@ -165,7 +165,7 @@ export class GlobalStateSynchroniser extends AbstractSynchroniser implements IUs
if (local) {
// update local
this.logService.trace('UI State: Updating local ui state...');
await this.backupLocal(VSBuffer.fromString(JSON.stringify(localUserData)));
await this.backupLocal(VSBuffer.fromString(JSON.stringify(localUserData, null, '\t')));
await this.writeLocalGlobalState(local);
this.logService.info('UI State: Updated local ui state');
}

View File

@@ -8,6 +8,11 @@ import { Event, Emitter } from 'vs/base/common/event';
import { Disposable } from 'vs/base/common/lifecycle';
import { IUserDataSyncLogService, IUserDataSyncService, SyncStatus, IUserDataAutoSyncService, UserDataSyncError, UserDataSyncErrorCode, IUserDataSyncEnablementService } from 'vs/platform/userDataSync/common/userDataSync';
import { IAuthenticationTokenService } from 'vs/platform/authentication/common/authentication';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
type AutoSyncTriggerClassification = {
source: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true };
};
export class UserDataAutoSyncService extends Disposable implements IUserDataAutoSyncService {
@@ -25,6 +30,7 @@ export class UserDataAutoSyncService extends Disposable implements IUserDataAuto
@IUserDataSyncService private readonly userDataSyncService: IUserDataSyncService,
@IUserDataSyncLogService private readonly logService: IUserDataSyncLogService,
@IAuthenticationTokenService private readonly authTokenService: IAuthenticationTokenService,
@ITelemetryService private readonly telemetryService: ITelemetryService,
) {
super();
this.updateEnablement(false, true);
@@ -32,7 +38,7 @@ export class UserDataAutoSyncService extends Disposable implements IUserDataAuto
this._register(Event.any<any>(authTokenService.onDidChangeToken)(() => this.updateEnablement(true, true)));
this._register(Event.any<any>(userDataSyncService.onDidChangeStatus)(() => this.updateEnablement(true, true)));
this._register(this.userDataSyncEnablementService.onDidChangeEnablement(() => this.updateEnablement(true, false)));
this._register(this.userDataSyncEnablementService.onDidChangeResourceEnablement(() => this.triggerAutoSync()));
this._register(this.userDataSyncEnablementService.onDidChangeResourceEnablement(() => this.triggerAutoSync(['resourceEnablement'])));
}
private async updateEnablement(stopIfDisabled: boolean, auto: boolean): Promise<void> {
@@ -99,7 +105,8 @@ export class UserDataAutoSyncService extends Disposable implements IUserDataAuto
this.successiveFailures = 0;
}
async triggerAutoSync(): Promise<void> {
async triggerAutoSync(sources: string[]): Promise<void> {
sources.forEach(source => this.telemetryService.publicLog2<{ source: string }, AutoSyncTriggerClassification>('sync/triggerAutoSync', { source }));
if (this.enabled) {
return this.syncDelayer.trigger(() => {
this.logService.info('Auto Sync: Triggered.');

View File

@@ -278,7 +278,7 @@ export interface IUserDataSyncService {
readonly conflictsSources: SyncSource[];
readonly onDidChangeConflicts: Event<SyncSource[]>;
readonly onDidChangeLocal: Event<void>;
readonly onDidChangeLocal: Event<SyncSource>;
readonly onSyncErrors: Event<[SyncSource, UserDataSyncError][]>;
readonly lastSyncTime: number | undefined;
@@ -299,7 +299,7 @@ export const IUserDataAutoSyncService = createDecorator<IUserDataAutoSyncService
export interface IUserDataAutoSyncService {
_serviceBrand: any;
readonly onError: Event<UserDataSyncError>;
triggerAutoSync(): Promise<void>;
triggerAutoSync(sources: string[]): Promise<void>;
}
export const IUserDataSyncUtilService = createDecorator<IUserDataSyncUtilService>('IUserDataSyncUtilService');

View File

@@ -86,7 +86,7 @@ export class UserDataAutoSyncChannel implements IServerChannel {
call(context: any, command: string, args?: any): Promise<any> {
switch (command) {
case 'triggerAutoSync': return this.service.triggerAutoSync();
case 'triggerAutoSync': return this.service.triggerAutoSync(args[0]);
}
throw new Error('Invalid call');
}

View File

@@ -34,7 +34,7 @@ export class UserDataSyncService extends Disposable implements IUserDataSyncServ
private _onDidChangeStatus: Emitter<SyncStatus> = this._register(new Emitter<SyncStatus>());
readonly onDidChangeStatus: Event<SyncStatus> = this._onDidChangeStatus.event;
readonly onDidChangeLocal: Event<void>;
readonly onDidChangeLocal: Event<SyncSource>;
private _conflictsSources: SyncSource[] = [];
get conflictsSources(): SyncSource[] { return this._conflictsSources; }
@@ -74,7 +74,7 @@ export class UserDataSyncService extends Disposable implements IUserDataSyncServ
}
this._lastSyncTime = this.storageService.getNumber(LAST_SYNC_TIME_KEY, StorageScope.GLOBAL, undefined);
this.onDidChangeLocal = Event.any(...this.synchronisers.map(s => s.onDidChangeLocal));
this.onDidChangeLocal = Event.any(...this.synchronisers.map(s => Event.map(s.onDidChangeLocal, () => s.source)));
}
async pull(): Promise<void> {

View File

@@ -8,6 +8,7 @@ import { Event } from 'vs/base/common/event';
import { IElectronService } from 'vs/platform/electron/node/electron';
import { UserDataAutoSyncService as BaseUserDataAutoSyncService } from 'vs/platform/userDataSync/common/userDataAutoSyncService';
import { IAuthenticationTokenService } from 'vs/platform/authentication/common/authentication';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
export class UserDataAutoSyncService extends BaseUserDataAutoSyncService {
@@ -17,15 +18,15 @@ export class UserDataAutoSyncService extends BaseUserDataAutoSyncService {
@IElectronService electronService: IElectronService,
@IUserDataSyncLogService logService: IUserDataSyncLogService,
@IAuthenticationTokenService authTokenService: IAuthenticationTokenService,
@ITelemetryService telemetryService: ITelemetryService,
) {
super(userDataSyncEnablementService, userDataSyncService, logService, authTokenService);
super(userDataSyncEnablementService, userDataSyncService, logService, authTokenService, telemetryService);
// Sync immediately if there is a local change.
this._register(Event.debounce(Event.any<any>(
electronService.onWindowFocus,
electronService.onWindowOpen,
this._register(Event.debounce<string, string[]>(Event.any<string>(
Event.map(electronService.onWindowFocus, () => 'windowFocus'),
Event.map(electronService.onWindowOpen, () => 'windowOpen'),
userDataSyncService.onDidChangeLocal,
), () => undefined, 500)(() => this.triggerAutoSync()));
), (last, source) => last ? [...last, source] : [source], 1000)(sources => this.triggerAutoSync(sources)));
}
}