Skip to content

Commit

Permalink
sketch user data sync store service with log in
Browse files Browse the repository at this point in the history
  • Loading branch information
sandy081 committed Sep 17, 2019
1 parent c9258e8 commit 874d2fc
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 78 deletions.
1 change: 1 addition & 0 deletions src/vs/platform/product/common/productService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ export interface IProductConfiguration {

readonly msftInternalDomains?: string[];
readonly linkProtectionTrustedDomains?: readonly string[];
readonly settingsSyncStoreUrl?: string;
}

export interface IExeBasedExtensionTip {
Expand Down
46 changes: 4 additions & 42 deletions src/vs/platform/userDataSync/common/userDataSync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,38 +17,6 @@ export enum UserDataSyncStoreErrorCode {
Unknown = 'Unknown'
}

export function markAsUserDataSyncStoreError(error: Error, code: UserDataSyncStoreErrorCode): Error {
error.name = code ? `${code} (UserDataSyncStoreError)` : `UserDataSyncStoreError`;

return error;
}

export function toUserDataSyncStoreErrorCode(error: Error | undefined | null): UserDataSyncStoreErrorCode {

// Guard against abuse
if (!error) {
return UserDataSyncStoreErrorCode.Unknown;
}

// FileSystemProviderError comes with the code
if (error instanceof UserDataSyncStoreError) {
return error.code;
}

// Any other error, check for name match by assuming that the error
// went through the markAsUserDataSyncStoreError() method
const match = /^(.+) \(UserDataSyncStoreError\)$/.exec(error.name);
if (!match) {
return UserDataSyncStoreErrorCode.Unknown;
}

switch (match[1]) {
case UserDataSyncStoreErrorCode.Rejected: return UserDataSyncStoreErrorCode.Rejected;
}

return UserDataSyncStoreErrorCode.Unknown;
}

export class UserDataSyncStoreError extends Error {

constructor(message: string, public readonly code: UserDataSyncStoreErrorCode) {
Expand All @@ -57,23 +25,17 @@ export class UserDataSyncStoreError extends Error {

}

export interface IUserDataSyncStore {
readonly id: string;
readonly name: string;
read(key: string): Promise<IUserData | null>;
write(key: string, content: string, ref: string | null): Promise<string>;
}

export const IUserDataSyncStoreService = createDecorator<IUserDataSyncStoreService>('IUserDataSyncStoreService');

export interface IUserDataSyncStoreService {
_serviceBrand: undefined;

readonly onDidChangeEnablement: Event<boolean>;
readonly enabled: boolean;

registerUserDataSyncStore(userDataSyncStore: IUserDataSyncStore): void;
deregisterUserDataSyncStore(): void;
readonly loggedIn: boolean;
readonly onDidChangeLoggedIn: Event<boolean>;
login(): Promise<void>;
logout(): Promise<void>;

read(key: string): Promise<IUserData | null>;
write(key: string, content: string, ref: string | null): Promise<string>;
Expand Down
2 changes: 1 addition & 1 deletion src/vs/platform/userDataSync/common/userDataSyncService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export class UserDataSyncService extends Disposable implements IUserDataSyncServ
this.instantiationService.createInstance(SettingsSynchroniser)
];
this.updateStatus();
this._register(Event.any(this.userDataSyncStoreService.onDidChangeEnablement, ...this.synchronisers.map(s => Event.map(s.onDidChangeStatus, () => undefined)))(() => this.updateStatus()));
this._register(Event.any(...this.synchronisers.map(s => Event.map(s.onDidChangeStatus, () => undefined)))(() => this.updateStatus()));
this.onDidChangeLocal = Event.any(...this.synchronisers.map(s => s.onDidChangeLocal));
}

Expand Down
45 changes: 18 additions & 27 deletions src/vs/platform/userDataSync/common/userDataSyncStoreService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,54 +4,45 @@
*--------------------------------------------------------------------------------------------*/

import { Disposable, } from 'vs/base/common/lifecycle';
import { IUserData, IUserDataSyncStoreService } from 'vs/platform/userDataSync/common/userDataSync';
import { IProductService } from 'vs/platform/product/common/productService';
import { Emitter, Event } from 'vs/base/common/event';
import { IUserDataSyncStore, IUserData, UserDataSyncStoreError, toUserDataSyncStoreErrorCode, IUserDataSyncStoreService } from 'vs/platform/userDataSync/common/userDataSync';
import { ILogService } from 'vs/platform/log/common/log';

export class UserDataSyncStoreService extends Disposable implements IUserDataSyncStoreService {

_serviceBrand: any;

private userDataSyncStore: IUserDataSyncStore | null = null;
get enabled(): boolean { return !!this.productService.settingsSyncStoreUrl; }

get enabled(): boolean { return !!this.userDataSyncStore; }
private readonly _onDidChangeEnablement: Emitter<boolean> = this._register(new Emitter<boolean>());
readonly onDidChangeEnablement: Event<boolean> = this._onDidChangeEnablement.event;
private _loggedIn: boolean = false;
get loggedIn(): boolean { return this._loggedIn; }
private readonly _onDidChangeLoggedIn: Emitter<boolean> = this._register(new Emitter<boolean>());
readonly onDidChangeLoggedIn: Event<boolean> = this._onDidChangeLoggedIn.event;

constructor(
@ILogService private logService: ILogService
@IProductService private readonly productService: IProductService,
) {
super();
}

registerUserDataSyncStore(userDataSyncStore: IUserDataSyncStore): void {
if (this.userDataSyncStore) {
this.logService.warn(`A user data sync store '${this.userDataSyncStore.name}' already registered. Hence ignoring the newly registered '${userDataSyncStore.name}' store.`);
return;
}
this.userDataSyncStore = userDataSyncStore;
this._onDidChangeEnablement.fire(true);
async login(): Promise<void> {
}

deregisterUserDataSyncStore(): void {
this.userDataSyncStore = null;
this._onDidChangeEnablement.fire(false);
async logout(): Promise<void> {
}

read(key: string): Promise<IUserData | null> {
if (!this.userDataSyncStore) {
throw new Error('No user sync store exists.');
async read(key: string): Promise<IUserData | null> {
if (!this.enabled) {
return Promise.reject(new Error('No settings sync store url configured.'));
}
return this.userDataSyncStore.read(key)
.then(null, error => Promise.reject(new UserDataSyncStoreError(error.message, toUserDataSyncStoreErrorCode(error))));
return null;
}

write(key: string, content: string, ref: string | null): Promise<string> {
if (!this.userDataSyncStore) {
throw new Error('No user sync store exists.');
async write(key: string, content: string, ref: string | null): Promise<string> {
if (!this.enabled) {
return Promise.reject(new Error('No settings sync store url configured.'));
}
return this.userDataSyncStore.write(key, content, ref)
.then(null, error => Promise.reject(new UserDataSyncStoreError(error.message, toUserDataSyncStoreErrorCode(error))));
return '';
}

}
3 changes: 2 additions & 1 deletion src/vs/workbench/api/common/extHostTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ import { generateUuid } from 'vs/base/common/uuid';
import * as vscode from 'vscode';
import { FileSystemProviderErrorCode, markAsFileSystemProviderError } from 'vs/platform/files/common/files';
import { RemoteAuthorityResolverErrorCode } from 'vs/platform/remote/common/remoteAuthorityResolver';
import { UserDataSyncStoreErrorCode, markAsUserDataSyncStoreError } from 'vs/platform/userDataSync/common/userDataSync';
import { UserDataSyncStoreErrorCode } from 'vs/platform/userDataSync/common/userDataSync';
import { markAsUserDataSyncStoreError } from 'vs/workbench/services/userDataSync/common/userDataSyncStores';

function es5ClassCompat(target: Function): any {
///@ts-ignore
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/

import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions, IWorkbenchContribution } from 'vs/workbench/common/contributions';
import { IUserDataSyncService, SyncStatus, USER_DATA_PREVIEW_SCHEME, IUserDataSyncStoreService } from 'vs/platform/userDataSync/common/userDataSync';
import { IUserDataSyncService, SyncStatus, USER_DATA_PREVIEW_SCHEME } from 'vs/platform/userDataSync/common/userDataSync';
import { localize } from 'vs/nls';
import { Disposable, MutableDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
Expand Down Expand Up @@ -52,22 +52,19 @@ class UserDataSyncContribution extends Disposable implements IWorkbenchContribut
@IFileService fileService: IFileService,
@IConfigurationService private readonly configurationService: IConfigurationService,
@IUserDataSyncService private readonly userDataSyncService: IUserDataSyncService,
@IUserDataSyncStoreService private readonly userDataSyncStoreService: IUserDataSyncStoreService,
) {
super();
this._register(fileService.registerProvider(USER_DATA_PREVIEW_SCHEME, new InMemoryFileSystemProvider()));
this.sync(true);
this._register(Event.any<any>(
Event.filter(this.configurationService.onDidChangeConfiguration, e => e.affectsConfiguration('userConfiguration.enableSync') && this.configurationService.getValue<boolean>('userConfiguration.enableSync')),
this.userDataSyncStoreService.onDidChangeEnablement)
this._register(Event.filter(this.configurationService.onDidChangeConfiguration, e => e.affectsConfiguration('userConfiguration.enableSync') && this.configurationService.getValue<boolean>('userConfiguration.enableSync'))
(() => this.sync(true)));

// Sync immediately if there is a local change.
this._register(Event.debounce(this.userDataSyncService.onDidChangeLocal, () => undefined, 500)(() => this.sync(false)));
}

private async sync(loop: boolean): Promise<void> {
if (this.configurationService.getValue<boolean>('userConfiguration.enableSync') && this.userDataSyncStoreService.enabled) {
if (this.configurationService.getValue<boolean>('userConfiguration.enableSync')) {
try {
await this.userDataSyncService.sync();
} catch (e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,43 @@
*--------------------------------------------------------------------------------------------*/

import { Event, Emitter } from 'vs/base/common/event';
import { IUserData } from 'vs/platform/userDataSync/common/userDataSync';
import { IUserData, UserDataSyncStoreErrorCode, UserDataSyncStoreError } from 'vs/platform/userDataSync/common/userDataSync';
import { Disposable } from 'vs/base/common/lifecycle';
import { values } from 'vs/base/common/map';
import { Registry } from 'vs/platform/registry/common/platform';

export function markAsUserDataSyncStoreError(error: Error, code: UserDataSyncStoreErrorCode): Error {
error.name = code ? `${code} (UserDataSyncStoreError)` : `UserDataSyncStoreError`;

return error;
}

export function toUserDataSyncStoreErrorCode(error: Error | undefined | null): UserDataSyncStoreErrorCode {

// Guard against abuse
if (!error) {
return UserDataSyncStoreErrorCode.Unknown;
}

// FileSystemProviderError comes with the code
if (error instanceof UserDataSyncStoreError) {
return error.code;
}

// Any other error, check for name match by assuming that the error
// went through the markAsUserDataSyncStoreError() method
const match = /^(.+) \(UserDataSyncStoreError\)$/.exec(error.name);
if (!match) {
return UserDataSyncStoreErrorCode.Unknown;
}

switch (match[1]) {
case UserDataSyncStoreErrorCode.Rejected: return UserDataSyncStoreErrorCode.Rejected;
}

return UserDataSyncStoreErrorCode.Unknown;
}

export interface IUserDataSyncStore {
readonly id: string;
readonly name: string;
Expand Down

0 comments on commit 874d2fc

Please sign in to comment.