提交 467c9990 编写于 作者: S Sandeep Somavarapu

Fix #86297

上级 f4b952c9
...@@ -14,6 +14,11 @@ import { KeybindingsSynchroniser } from 'vs/platform/userDataSync/common/keybind ...@@ -14,6 +14,11 @@ import { KeybindingsSynchroniser } from 'vs/platform/userDataSync/common/keybind
import { GlobalStateSynchroniser } from 'vs/platform/userDataSync/common/globalStateSync'; import { GlobalStateSynchroniser } from 'vs/platform/userDataSync/common/globalStateSync';
import { toErrorMessage } from 'vs/base/common/errorMessage'; import { toErrorMessage } from 'vs/base/common/errorMessage';
import { localize } from 'vs/nls'; 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 { export class UserDataSyncService extends Disposable implements IUserDataSyncService {
...@@ -41,6 +46,7 @@ export class UserDataSyncService extends Disposable implements IUserDataSyncServ ...@@ -41,6 +46,7 @@ export class UserDataSyncService extends Disposable implements IUserDataSyncServ
@ISettingsSyncService private readonly settingsSynchroniser: ISettingsSyncService, @ISettingsSyncService private readonly settingsSynchroniser: ISettingsSyncService,
@IUserDataSyncLogService private readonly logService: IUserDataSyncLogService, @IUserDataSyncLogService private readonly logService: IUserDataSyncLogService,
@IUserDataAuthTokenService private readonly userDataAuthTokenService: IUserDataAuthTokenService, @IUserDataAuthTokenService private readonly userDataAuthTokenService: IUserDataAuthTokenService,
@ITelemetryService private readonly telemetryService: ITelemetryService,
) { ) {
super(); super();
this.keybindingsSynchroniser = this._register(this.instantiationService.createInstance(KeybindingsSynchroniser)); this.keybindingsSynchroniser = this._register(this.instantiationService.createInstance(KeybindingsSynchroniser));
...@@ -252,13 +258,20 @@ export class UserDataSyncService extends Disposable implements IUserDataSyncServ ...@@ -252,13 +258,20 @@ export class UserDataSyncService extends Disposable implements IUserDataSyncServ
} }
private updateStatus(): void { private updateStatus(): void {
this._conflictsSource = this.computeConflictsSource(); const status = this.computeStatus();
this.setStatus(this.computeStatus());
}
private setStatus(status: SyncStatus): void {
if (this._status !== status) { if (this._status !== status) {
const oldStatus = this._status;
const oldConflictsSource = this._conflictsSource;
this._conflictsSource = this.computeConflictsSource();
this._status = status; 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); this._onDidChangeStatus.fire(status);
} }
} }
......
...@@ -41,11 +41,10 @@ import type { IEditorContribution } from 'vs/editor/common/editorCommon'; ...@@ -41,11 +41,10 @@ import type { IEditorContribution } from 'vs/editor/common/editorCommon';
import type { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import type { ICodeEditor } from 'vs/editor/browser/editorBrowser';
import { FloatingClickWidget } from 'vs/workbench/browser/parts/editor/editorWidgets'; import { FloatingClickWidget } from 'vs/workbench/browser/parts/editor/editorWidgets';
import { registerEditorContribution } from 'vs/editor/browser/editorExtensions'; import { registerEditorContribution } from 'vs/editor/browser/editorExtensions';
import { areSame } from 'vs/platform/userDataSync/common/settingsMerge';
import { getIgnoredSettings } from 'vs/platform/userDataSync/common/settingsSync';
import type { IEditorInput } from 'vs/workbench/common/editor'; import type { IEditorInput } from 'vs/workbench/common/editor';
import { Action } from 'vs/base/common/actions'; import { Action } from 'vs/base/common/actions';
import { IPreferencesService } from 'vs/workbench/services/preferences/common/preferences'; import { IPreferencesService } from 'vs/workbench/services/preferences/common/preferences';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
const enum AuthStatus { const enum AuthStatus {
Initializing = 'Initializing', Initializing = 'Initializing',
...@@ -65,6 +64,14 @@ function getSyncAreaLabel(source: SyncSource): string { ...@@ -65,6 +64,14 @@ function getSyncAreaLabel(source: SyncSource): string {
} }
} }
type FirstTimeSyncClassification = {
action: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true };
};
type SyncErrorClassification = {
source: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true };
};
export class UserDataSyncWorkbenchContribution extends Disposable implements IWorkbenchContribution { export class UserDataSyncWorkbenchContribution extends Disposable implements IWorkbenchContribution {
private static readonly ENABLEMENT_SETTING = 'sync.enable'; private static readonly ENABLEMENT_SETTING = 'sync.enable';
...@@ -92,8 +99,9 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo ...@@ -92,8 +99,9 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
@IOutputService private readonly outputService: IOutputService, @IOutputService private readonly outputService: IOutputService,
@IUserDataAuthTokenService private readonly userDataAuthTokenService: IUserDataAuthTokenService, @IUserDataAuthTokenService private readonly userDataAuthTokenService: IUserDataAuthTokenService,
@IUserDataAutoSyncService userDataAutoSyncService: IUserDataAutoSyncService, @IUserDataAutoSyncService userDataAutoSyncService: IUserDataAutoSyncService,
@ITextModelService private readonly textModelResolverService: ITextModelService, @ITextModelService textModelResolverService: ITextModelService,
@IPreferencesService private readonly preferencesService: IPreferencesService, @IPreferencesService private readonly preferencesService: IPreferencesService,
@ITelemetryService private readonly telemetryService: ITelemetryService,
) { ) {
super(); super();
this.userDataSyncStore = getUserDataSyncStore(configurationService); this.userDataSyncStore = getUserDataSyncStore(configurationService);
...@@ -253,6 +261,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo ...@@ -253,6 +261,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
private onAutoSyncError(code: UserDataSyncErrorCode, source?: SyncSource): void { private onAutoSyncError(code: UserDataSyncErrorCode, source?: SyncSource): void {
switch (code) { switch (code) {
case UserDataSyncErrorCode.TooManyFailures: case UserDataSyncErrorCode.TooManyFailures:
this.telemetryService.publicLog2('sync/errorTooMany');
this.disableSync(); this.disableSync();
this.notificationService.notify({ this.notificationService.notify({
severity: Severity.Error, severity: Severity.Error,
...@@ -263,6 +272,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo ...@@ -263,6 +272,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
}); });
return; return;
case UserDataSyncErrorCode.TooLarge: case UserDataSyncErrorCode.TooLarge:
this.telemetryService.publicLog2<{ source: string }, SyncErrorClassification>('sync/errorTooLarge', { source: source! });
if (source === SyncSource.Keybindings || source === SyncSource.Settings) { if (source === SyncSource.Keybindings || source === SyncSource.Settings) {
const sourceArea = getSyncAreaLabel(source); const sourceArea = getSyncAreaLabel(source);
this.disableSync(); this.disableSync();
...@@ -418,9 +428,17 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo ...@@ -418,9 +428,17 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
} }
); );
switch (result.choice) { switch (result.choice) {
case 0: await this.userDataSyncService.sync(); break; case 0:
case 1: throw canceled(); this.telemetryService.publicLog2<{ action: string }, FirstTimeSyncClassification>('sync/firstTimeSync', { action: 'merge' });
case 2: await this.userDataSyncService.pull(); break; await this.userDataSyncService.sync();
break;
case 1:
this.telemetryService.publicLog2<{ action: string }, FirstTimeSyncClassification>('sync/firstTimeSync', { action: 'cancelled' });
throw canceled();
case 2:
this.telemetryService.publicLog2<{ action: string }, FirstTimeSyncClassification>('sync/firstTimeSync', { action: 'replace-local' });
await this.userDataSyncService.pull();
break;
} }
} }
...@@ -441,6 +459,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo ...@@ -441,6 +459,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
if (result.confirmed) { if (result.confirmed) {
await this.disableSync(); await this.disableSync();
if (result.checkboxChecked) { if (result.checkboxChecked) {
this.telemetryService.publicLog2('sync/turnOffEveryWhere');
await this.userDataSyncService.reset(); await this.userDataSyncService.reset();
} }
} }
...@@ -492,7 +511,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo ...@@ -492,7 +511,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
} }
if (previewResource) { if (previewResource) {
const remoteContentResource = toRemoteContentResource(this.userDataSyncService.conflictsSource!); const remoteContentResource = toRemoteContentResource(this.userDataSyncService.conflictsSource!);
const editor = await this.editorService.openEditor({ await this.editorService.openEditor({
leftResource: remoteContentResource, leftResource: remoteContentResource,
rightResource: previewResource, rightResource: previewResource,
label, label,
...@@ -502,27 +521,6 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo ...@@ -502,27 +521,6 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
revealIfVisible: true, revealIfVisible: true,
}, },
}); });
if (editor?.input) {
const disposable = editor.input.onDispose(async () => {
disposable.dispose();
const source = getSyncSourceFromRemoteContentResource(remoteContentResource);
if (source === undefined || this.userDataSyncService.conflictsSource !== source) {
return;
}
const remoteModelRef = await this.textModelResolverService.createModelReference(remoteContentResource);
const previewModelRef = await this.textModelResolverService.createModelReference(previewResource!);
const remoteModelContent = remoteModelRef.object.textEditorModel.getValue();
const preivewContent = previewModelRef.object.textEditorModel.getValue();
remoteModelRef.dispose();
previewModelRef.dispose();
if (remoteModelContent !== preivewContent
|| (source === SyncSource.Settings && !areSame(remoteModelContent, preivewContent, getIgnoredSettings(this.configurationService)))) {
return;
}
await this.userDataSyncService.resolveConflictsAndContinueSync(preivewContent);
});
}
} }
} }
...@@ -682,6 +680,11 @@ class UserDataRemoteContentProvider implements ITextModelContentProvider { ...@@ -682,6 +680,11 @@ class UserDataRemoteContentProvider implements ITextModelContentProvider {
} }
} }
type SyncConflictsClassification = {
source: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true };
action: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true };
};
class AcceptChangesContribution extends Disposable implements IEditorContribution { class AcceptChangesContribution extends Disposable implements IEditorContribution {
static get(editor: ICodeEditor): AcceptChangesContribution { static get(editor: ICodeEditor): AcceptChangesContribution {
...@@ -700,6 +703,7 @@ class AcceptChangesContribution extends Disposable implements IEditorContributio ...@@ -700,6 +703,7 @@ class AcceptChangesContribution extends Disposable implements IEditorContributio
@INotificationService private readonly notificationService: INotificationService, @INotificationService private readonly notificationService: INotificationService,
@IDialogService private readonly dialogService: IDialogService, @IDialogService private readonly dialogService: IDialogService,
@IConfigurationService private readonly configurationService: IConfigurationService, @IConfigurationService private readonly configurationService: IConfigurationService,
@ITelemetryService private readonly telemetryService: ITelemetryService
) { ) {
super(); super();
...@@ -760,6 +764,7 @@ class AcceptChangesContribution extends Disposable implements IEditorContributio ...@@ -760,6 +764,7 @@ class AcceptChangesContribution extends Disposable implements IEditorContributio
if (model) { if (model) {
const conflictsSource = this.userDataSyncService.conflictsSource; const conflictsSource = this.userDataSyncService.conflictsSource;
const syncSource = getSyncSourceFromRemoteContentResource(model.uri); const syncSource = getSyncSourceFromRemoteContentResource(model.uri);
this.telemetryService.publicLog2<{ source: string, action: string }, SyncConflictsClassification>('sync/handleConflicts', { source: conflictsSource!, action: syncSource !== undefined ? 'replaceLocal' : 'apply' });
if (syncSource !== undefined) { if (syncSource !== undefined) {
const syncAreaLabel = getSyncAreaLabel(syncSource); const syncAreaLabel = getSyncAreaLabel(syncSource);
const result = await this.dialogService.confirm({ const result = await this.dialogService.confirm({
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册