提交 eb1f88b5 编写于 作者: S Sandeep Somavarapu

#91556 Add telemetry to auto sync trigger sources

上级 57f7d837
......@@ -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.');
......
......@@ -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');
......
......@@ -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');
}
......
......@@ -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> {
......
......@@ -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)));
}
}
......@@ -10,6 +10,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
import { UserDataSyncTrigger } from 'vs/workbench/contrib/userDataSync/browser/userDataSyncTrigger';
import { IHostService } from 'vs/workbench/services/host/browser/host';
import { IAuthenticationTokenService } from 'vs/platform/authentication/common/authentication';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
export class UserDataAutoSyncService extends BaseUserDataAutoSyncService {
......@@ -20,15 +21,15 @@ export class UserDataAutoSyncService extends BaseUserDataAutoSyncService {
@IAuthenticationTokenService authTokenService: IAuthenticationTokenService,
@IInstantiationService instantiationService: IInstantiationService,
@IHostService hostService: IHostService,
@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>(
userDataSyncService.onDidChangeLocal,
this._register(Event.debounce<string, string[]>(Event.any<string>(
Event.map(hostService.onDidChangeFocus, () => 'windowFocus'),
instantiationService.createInstance(UserDataSyncTrigger).onDidTriggerSync,
hostService.onDidChangeFocus
), () => undefined, 500)(() => this.triggerAutoSync()));
userDataSyncService.onDidChangeLocal,
), (last, source) => last ? [...last, source] : [source], 1000)(sources => this.triggerAutoSync(sources)));
}
}
......@@ -163,7 +163,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
this.registerActions();
this.initializeActiveAccount().then(_ => {
if (!isWeb) {
this._register(instantiationService.createInstance(UserDataSyncTrigger).onDidTriggerSync(() => userDataAutoSyncService.triggerAutoSync()));
this._register(instantiationService.createInstance(UserDataSyncTrigger).onDidTriggerSync(source => userDataAutoSyncService.triggerAutoSync([source])));
}
});
......
......@@ -16,8 +16,8 @@ import { IViewlet } from 'vs/workbench/common/viewlet';
export class UserDataSyncTrigger extends Disposable {
private readonly _onDidTriggerSync: Emitter<void> = this._register(new Emitter<void>());
readonly onDidTriggerSync: Event<void> = this._onDidTriggerSync.event;
private readonly _onDidTriggerSync: Emitter<string> = this._register(new Emitter<string>());
readonly onDidTriggerSync: Event<string> = this._onDidTriggerSync.event;
constructor(
@IEditorService editorService: IEditorService,
......@@ -25,37 +25,44 @@ export class UserDataSyncTrigger extends Disposable {
@IViewletService viewletService: IViewletService,
) {
super();
this._register(Event.debounce(Event.any<any>(
Event.filter(editorService.onDidActiveEditorChange, () => this.isUserDataEditorInput(editorService.activeEditor)),
Event.filter(viewletService.onDidViewletOpen, viewlet => this.isUserDataViewlet(viewlet))
), () => undefined, 500)(() => this._onDidTriggerSync.fire()));
this._register(Event.any<string | undefined>(
Event.map(editorService.onDidActiveEditorChange, () => this.getUserDataEditorInputSource(editorService.activeEditor)),
Event.map(viewletService.onDidViewletOpen, viewlet => this.getUserDataViewletSource(viewlet))
)(source => {
if (source) {
this._onDidTriggerSync.fire(source);
}
}));
}
private isUserDataViewlet(viewlet: IViewlet): boolean {
return viewlet.getId() === VIEWLET_ID;
private getUserDataViewletSource(viewlet: IViewlet): string | undefined {
if (viewlet.getId() === VIEWLET_ID) {
return 'extensionsViewlet';
}
return undefined;
}
private isUserDataEditorInput(editorInput: IEditorInput | undefined): boolean {
private getUserDataEditorInputSource(editorInput: IEditorInput | undefined): string | undefined {
if (!editorInput) {
return false;
return undefined;
}
if (editorInput instanceof SettingsEditor2Input) {
return true;
return 'settingsEditor';
}
if (editorInput instanceof PreferencesEditorInput) {
return true;
return 'settingsEditor';
}
if (editorInput instanceof KeybindingsEditorInput) {
return true;
return 'keybindingsEditor';
}
const resource = editorInput.resource;
if (isEqual(resource, this.workbenchEnvironmentService.settingsResource)) {
return true;
return 'settingsEditor';
}
if (isEqual(resource, this.workbenchEnvironmentService.keybindingsResource)) {
return true;
return 'keybindingsEditor';
}
return false;
return undefined;
}
}
......@@ -24,8 +24,8 @@ export class UserDataAutoSyncService extends Disposable implements IUserDataAuto
this.channel = sharedProcessService.getChannel('userDataAutoSync');
}
triggerAutoSync(): Promise<void> {
return this.channel.call('triggerAutoSync');
triggerAutoSync(sources: string[]): Promise<void> {
return this.channel.call('triggerAutoSync', [sources]);
}
}
......
......@@ -22,7 +22,7 @@ export class UserDataSyncService extends Disposable implements IUserDataSyncServ
private _onDidChangeStatus: Emitter<SyncStatus> = this._register(new Emitter<SyncStatus>());
readonly onDidChangeStatus: Event<SyncStatus> = this._onDidChangeStatus.event;
get onDidChangeLocal(): Event<void> { return this.channel.listen('onDidChangeLocal'); }
get onDidChangeLocal(): Event<SyncSource> { return this.channel.listen<SyncSource>('onDidChangeLocal'); }
private _conflictsSources: SyncSource[] = [];
get conflictsSources(): SyncSource[] { return this._conflictsSources; }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册