mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-29 09:35:38 -05:00
Merge from vscode 3c6f6af7347d38e87bc6406024e8dcf9e9bce229 (#8962)
* Merge from vscode 3c6f6af7347d38e87bc6406024e8dcf9e9bce229 * skip failing tests * update mac build image
This commit is contained in:
committed by
Karl Burtram
parent
0eaee18dc4
commit
fefe1454de
@@ -3,22 +3,27 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IUserDataSyncService, SyncStatus, ISynchroniser, IUserDataSyncStoreService, SyncSource, ISettingsSyncService, IUserDataSyncLogService, IUserDataAuthTokenService } from 'vs/platform/userDataSync/common/userDataSync';
|
||||
import { IUserDataSyncService, SyncStatus, ISynchroniser, IUserDataSyncStoreService, SyncSource, ISettingsSyncService, IUserDataSyncLogService, IUserDataAuthTokenService, IUserDataSynchroniser } from 'vs/platform/userDataSync/common/userDataSync';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { SettingsSynchroniser } from 'vs/platform/userDataSync/common/settingsSync';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { ExtensionsSynchroniser } from 'vs/platform/userDataSync/common/extensionsSync';
|
||||
import { IExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
||||
import { KeybindingsSynchroniser } from 'vs/platform/userDataSync/common/keybindingsSync';
|
||||
import { GlobalStateSynchroniser } from 'vs/platform/userDataSync/common/globalStateSync';
|
||||
import { toErrorMessage } from 'vs/base/common/errorMessage';
|
||||
import { localize } from 'vs/nls';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
|
||||
type SyncConflictsClassification = {
|
||||
source?: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true };
|
||||
};
|
||||
|
||||
export class UserDataSyncService extends Disposable implements IUserDataSyncService {
|
||||
|
||||
_serviceBrand: any;
|
||||
|
||||
private readonly synchronisers: ISynchroniser[];
|
||||
private readonly synchronisers: IUserDataSynchroniser[];
|
||||
|
||||
private _status: SyncStatus = SyncStatus.Uninitialized;
|
||||
get status(): SyncStatus { return this._status; }
|
||||
@@ -40,6 +45,7 @@ export class UserDataSyncService extends Disposable implements IUserDataSyncServ
|
||||
@ISettingsSyncService private readonly settingsSynchroniser: ISettingsSyncService,
|
||||
@IUserDataSyncLogService private readonly logService: IUserDataSyncLogService,
|
||||
@IUserDataAuthTokenService private readonly userDataAuthTokenService: IUserDataAuthTokenService,
|
||||
@ITelemetryService private readonly telemetryService: ITelemetryService,
|
||||
) {
|
||||
super();
|
||||
this.keybindingsSynchroniser = this._register(this.instantiationService.createInstance(KeybindingsSynchroniser));
|
||||
@@ -88,31 +94,57 @@ export class UserDataSyncService extends Disposable implements IUserDataSyncServ
|
||||
}
|
||||
}
|
||||
|
||||
async sync(_continue?: boolean): Promise<boolean> {
|
||||
async sync(): Promise<void> {
|
||||
if (!this.userDataSyncStoreService.userDataSyncStore) {
|
||||
throw new Error('Not enabled');
|
||||
}
|
||||
if (!(await this.userDataAuthTokenService.getToken())) {
|
||||
throw new Error('Not Authenticated. Please sign in to start sync.');
|
||||
}
|
||||
if (this.status === SyncStatus.HasConflicts) {
|
||||
throw new Error(localize('resolve conflicts', "Please resolve conflicts before resuming sync."));
|
||||
}
|
||||
for (const synchroniser of this.synchronisers) {
|
||||
try {
|
||||
if (!await synchroniser.sync(_continue)) {
|
||||
return false;
|
||||
await synchroniser.sync();
|
||||
// do not continue if synchroniser has conflicts
|
||||
if (synchroniser.status === SyncStatus.HasConflicts) {
|
||||
return;
|
||||
}
|
||||
} catch (e) {
|
||||
this.logService.error(`${this.getSyncSource(synchroniser)}: ${toErrorMessage(e)}`);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
stop(): void {
|
||||
async resolveConflictsAndContinueSync(content: string): Promise<void> {
|
||||
const synchroniser = this.getSynchroniserInConflicts();
|
||||
if (!synchroniser) {
|
||||
throw new Error(localize('no synchroniser with conflicts', "No conflicts detected."));
|
||||
}
|
||||
await synchroniser.resolveConflicts(content);
|
||||
if (synchroniser.status !== SyncStatus.HasConflicts) {
|
||||
await this.sync();
|
||||
}
|
||||
}
|
||||
|
||||
async stop(): Promise<void> {
|
||||
if (!this.userDataSyncStoreService.userDataSyncStore) {
|
||||
throw new Error('Not enabled');
|
||||
}
|
||||
for (const synchroniser of this.synchronisers) {
|
||||
synchroniser.stop();
|
||||
await synchroniser.stop();
|
||||
}
|
||||
}
|
||||
|
||||
async restart(): Promise<void> {
|
||||
const synchroniser = this.getSynchroniserInConflicts();
|
||||
if (!synchroniser) {
|
||||
throw new Error(localize('no synchroniser with conflicts', "No conflicts detected."));
|
||||
}
|
||||
await synchroniser.restart();
|
||||
if (synchroniser.status !== SyncStatus.HasConflicts) {
|
||||
await this.sync();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,6 +193,15 @@ export class UserDataSyncService extends Disposable implements IUserDataSyncServ
|
||||
return false;
|
||||
}
|
||||
|
||||
async getRemoteContent(source: SyncSource): Promise<string | null> {
|
||||
for (const synchroniser of this.synchronisers) {
|
||||
if (synchroniser.source === source) {
|
||||
return synchroniser.getRemoteContent();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
async isFirstTimeSyncAndHasUserData(): Promise<boolean> {
|
||||
if (!this.userDataSyncStoreService.userDataSyncStore) {
|
||||
throw new Error('Not enabled');
|
||||
@@ -211,18 +252,21 @@ export class UserDataSyncService extends Disposable implements IUserDataSyncServ
|
||||
this.logService.info('Completed resetting local cache');
|
||||
}
|
||||
|
||||
removeExtension(identifier: IExtensionIdentifier): Promise<void> {
|
||||
return this.extensionsSynchroniser.removeExtension(identifier);
|
||||
}
|
||||
|
||||
private updateStatus(): void {
|
||||
this._conflictsSource = this.computeConflictsSource();
|
||||
this.setStatus(this.computeStatus());
|
||||
}
|
||||
|
||||
private setStatus(status: SyncStatus): void {
|
||||
const status = this.computeStatus();
|
||||
if (this._status !== status) {
|
||||
const oldStatus = this._status;
|
||||
const oldConflictsSource = this._conflictsSource;
|
||||
this._conflictsSource = this.computeConflictsSource();
|
||||
this._status = status;
|
||||
if (status === SyncStatus.HasConflicts) {
|
||||
// Log to telemetry when there is a sync conflict
|
||||
this.telemetryService.publicLog2<{ source: string }, SyncConflictsClassification>('sync/conflictsDetected', { source: this._conflictsSource! });
|
||||
}
|
||||
if (oldStatus === SyncStatus.HasConflicts && status === SyncStatus.Idle) {
|
||||
// Log to telemetry when conflicts are resolved
|
||||
this.telemetryService.publicLog2<{ source: string }, SyncConflictsClassification>('sync/conflictsResolved', { source: oldConflictsSource! });
|
||||
}
|
||||
this._onDidChangeStatus.fire(status);
|
||||
}
|
||||
}
|
||||
@@ -245,6 +289,11 @@ export class UserDataSyncService extends Disposable implements IUserDataSyncServ
|
||||
return synchroniser ? this.getSyncSource(synchroniser) : null;
|
||||
}
|
||||
|
||||
private getSynchroniserInConflicts(): IUserDataSynchroniser | null {
|
||||
const synchroniser = this.synchronisers.filter(s => s.status === SyncStatus.HasConflicts)[0];
|
||||
return synchroniser || null;
|
||||
}
|
||||
|
||||
private getSyncSource(synchroniser: ISynchroniser): SyncSource {
|
||||
if (synchroniser instanceof SettingsSynchroniser) {
|
||||
return SyncSource.Settings;
|
||||
@@ -255,7 +304,7 @@ export class UserDataSyncService extends Disposable implements IUserDataSyncServ
|
||||
if (synchroniser instanceof ExtensionsSynchroniser) {
|
||||
return SyncSource.Extensions;
|
||||
}
|
||||
return SyncSource.UIState;
|
||||
return SyncSource.GlobalState;
|
||||
}
|
||||
|
||||
private onDidChangeAuthTokenStatus(token: string | undefined): void {
|
||||
|
||||
Reference in New Issue
Block a user