mirror of
https://github.com/microsoft/vscode.git
synced 2026-05-08 17:19:48 +01:00
Merge pull request #157509 from microsoft/sandy081/subtle-halibut
make userdata sync store client profile aware
This commit is contained in:
@@ -667,14 +667,14 @@ export abstract class AbstractSynchroniser extends Disposable implements IUserDa
|
||||
return { ref: refOrLastSyncData, content };
|
||||
} else {
|
||||
const lastSyncUserData: IUserData | null = refOrLastSyncData ? { ref: refOrLastSyncData.ref, content: refOrLastSyncData.syncData ? JSON.stringify(refOrLastSyncData.syncData) : null } : null;
|
||||
return this.userDataSyncStoreService.read(this.resource, lastSyncUserData, this.syncHeaders);
|
||||
return this.userDataSyncStoreService.read(this.resource, lastSyncUserData, undefined, this.syncHeaders);
|
||||
}
|
||||
}
|
||||
|
||||
protected async updateRemoteUserData(content: string, ref: string | null): Promise<IRemoteUserData> {
|
||||
const machineId = await this.currentMachineIdPromise;
|
||||
const syncData: ISyncData = { version: this.version, machineId, content };
|
||||
ref = await this.userDataSyncStoreService.write(this.resource, JSON.stringify(syncData), ref, this.syncHeaders);
|
||||
ref = await this.userDataSyncStoreService.write(this.resource, JSON.stringify(syncData), ref, undefined, this.syncHeaders);
|
||||
return { ref, syncData };
|
||||
}
|
||||
|
||||
|
||||
@@ -480,7 +480,7 @@ export class UserDataSyncStoreTypeSynchronizer {
|
||||
|
||||
private async doSync(userDataSyncStoreType: UserDataSyncStoreType, syncHeaders: IHeaders): Promise<void> {
|
||||
// Read the global state from remote
|
||||
const globalStateUserData = await this.userDataSyncStoreClient.read(SyncResource.GlobalState, null, syncHeaders);
|
||||
const globalStateUserData = await this.userDataSyncStoreClient.readResource(SyncResource.GlobalState, null, syncHeaders);
|
||||
const remoteGlobalState = this.parseGlobalState(globalStateUserData) || { storage: {} };
|
||||
|
||||
// Update the sync store type
|
||||
@@ -489,7 +489,7 @@ export class UserDataSyncStoreTypeSynchronizer {
|
||||
// Write the global state to remote
|
||||
const machineId = await getServiceMachineId(this.environmentService, this.fileService, this.storageService);
|
||||
const syncDataToUpdate: ISyncData = { version: GLOBAL_STATE_DATA_VERSION, machineId, content: stringify(remoteGlobalState, false) };
|
||||
await this.userDataSyncStoreClient.write(SyncResource.GlobalState, JSON.stringify(syncDataToUpdate), globalStateUserData.ref, syncHeaders);
|
||||
await this.userDataSyncStoreClient.writeResource(SyncResource.GlobalState, JSON.stringify(syncDataToUpdate), globalStateUserData.ref, syncHeaders);
|
||||
}
|
||||
|
||||
private parseGlobalState({ content }: IUserData): IGlobalState | null {
|
||||
|
||||
@@ -156,7 +156,7 @@ export interface IResourceRefHandle {
|
||||
created: number;
|
||||
}
|
||||
|
||||
export type ServerResource = SyncResource | 'machines' | 'editSessions';
|
||||
export type ServerResource = SyncResource | 'machines' | 'editSessions' | 'profiles';
|
||||
export type UserDataSyncStoreType = 'insiders' | 'stable';
|
||||
|
||||
export const IUserDataSyncStoreManagementService = createDecorator<IUserDataSyncStoreManagementService>('IUserDataSyncStoreManagementService');
|
||||
@@ -168,7 +168,9 @@ export interface IUserDataSyncStoreManagementService {
|
||||
getPreviousUserDataSyncStore(): Promise<IUserDataSyncStore | undefined>;
|
||||
}
|
||||
|
||||
export interface IUserDataSyncStoreClient {
|
||||
export const IUserDataSyncStoreService = createDecorator<IUserDataSyncStoreService>('IUserDataSyncStoreService');
|
||||
export interface IUserDataSyncStoreService {
|
||||
readonly _serviceBrand: undefined;
|
||||
readonly onDidChangeDonotMakeRequestsUntil: Event<void>;
|
||||
readonly donotMakeRequestsUntil: Date | undefined;
|
||||
|
||||
@@ -176,20 +178,13 @@ export interface IUserDataSyncStoreClient {
|
||||
readonly onTokenSucceed: Event<void>;
|
||||
setAuthToken(token: string, type: string): void;
|
||||
|
||||
// Sync requests
|
||||
manifest(oldValue: IUserDataManifest | null, headers?: IHeaders): Promise<IUserDataManifest | null>;
|
||||
read(resource: ServerResource, oldValue: IUserData | null, headers?: IHeaders): Promise<IUserData>;
|
||||
write(resource: ServerResource, content: string, ref: string | null, headers?: IHeaders): Promise<string>;
|
||||
read(resource: ServerResource, oldValue: IUserData | null, profile?: string, headers?: IHeaders): Promise<IUserData>;
|
||||
write(resource: ServerResource, content: string, ref: string | null, profile?: string, headers?: IHeaders): Promise<string>;
|
||||
delete(resource: ServerResource, ref: string | null, profile?: string): Promise<void>;
|
||||
getAllRefs(resource: ServerResource, profile?: string): Promise<IResourceRefHandle[]>;
|
||||
resolveContent(resource: ServerResource, ref: string, profile?: string, headers?: IHeaders): Promise<string | null>;
|
||||
clear(): Promise<void>;
|
||||
delete(resource: ServerResource, ref: string | null): Promise<void>;
|
||||
|
||||
getAllRefs(resource: ServerResource): Promise<IResourceRefHandle[]>;
|
||||
resolveContent(resource: ServerResource, ref: string, headers?: IHeaders): Promise<string | null>;
|
||||
}
|
||||
|
||||
export const IUserDataSyncStoreService = createDecorator<IUserDataSyncStoreService>('IUserDataSyncStoreService');
|
||||
export interface IUserDataSyncStoreService extends IUserDataSyncStoreClient {
|
||||
readonly _serviceBrand: undefined;
|
||||
}
|
||||
|
||||
export const IUserDataSyncBackupStoreService = createDecorator<IUserDataSyncBackupStoreService>('IUserDataSyncBackupStoreService');
|
||||
|
||||
@@ -12,6 +12,7 @@ import { Mimes } from 'vs/base/common/mime';
|
||||
import { isWeb } from 'vs/base/common/platform';
|
||||
import { ConfigurationSyncStore } from 'vs/base/common/product';
|
||||
import { joinPath, relativePath } from 'vs/base/common/resources';
|
||||
import { join } from 'vs/base/common/path';
|
||||
import { isObject, isString } from 'vs/base/common/types';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { generateUuid } from 'vs/base/common/uuid';
|
||||
@@ -23,7 +24,7 @@ import { IProductService } from 'vs/platform/product/common/productService';
|
||||
import { asJson, asTextOrError, IRequestService, isSuccess as isSuccessContext } from 'vs/platform/request/common/request';
|
||||
import { getServiceMachineId } from 'vs/platform/externalServices/common/serviceMachineId';
|
||||
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
|
||||
import { CONFIGURATION_SYNC_STORE_KEY, HEADER_EXECUTION_ID, HEADER_OPERATION_ID, IAuthenticationProvider, IResourceRefHandle, IUserData, IUserDataManifest, IUserDataSyncLogService, IUserDataSyncStore, IUserDataSyncStoreClient, IUserDataSyncStoreManagementService, IUserDataSyncStoreService, ServerResource, SYNC_SERVICE_URL_TYPE, UserDataSyncErrorCode, UserDataSyncStoreError, UserDataSyncStoreType } from 'vs/platform/userDataSync/common/userDataSync';
|
||||
import { CONFIGURATION_SYNC_STORE_KEY, HEADER_EXECUTION_ID, HEADER_OPERATION_ID, IAuthenticationProvider, IResourceRefHandle, IUserData, IUserDataManifest, IUserDataSyncLogService, IUserDataSyncStore, IUserDataSyncStoreManagementService, IUserDataSyncStoreService, ServerResource, SYNC_SERVICE_URL_TYPE, UserDataSyncErrorCode, UserDataSyncStoreError, UserDataSyncStoreType } from 'vs/platform/userDataSync/common/userDataSync';
|
||||
|
||||
const SYNC_PREVIOUS_STORE = 'sync.previous.store';
|
||||
const DONOT_MAKE_REQUESTS_UNTIL_KEY = 'sync.donot-make-requests-until';
|
||||
@@ -140,7 +141,7 @@ export class UserDataSyncStoreManagementService extends AbstractUserDataSyncStor
|
||||
}
|
||||
}
|
||||
|
||||
export class UserDataSyncStoreClient extends Disposable implements IUserDataSyncStoreClient {
|
||||
export class UserDataSyncStoreClient extends Disposable {
|
||||
|
||||
private userDataSyncStoreUrl: URI | undefined;
|
||||
|
||||
@@ -230,12 +231,12 @@ export class UserDataSyncStoreClient extends Disposable implements IUserDataSync
|
||||
}
|
||||
}
|
||||
|
||||
async getAllRefs(resource: ServerResource): Promise<IResourceRefHandle[]> {
|
||||
async getAllResourceRefs(path: string): Promise<IResourceRefHandle[]> {
|
||||
if (!this.userDataSyncStoreUrl) {
|
||||
throw new Error('No settings sync store url configured.');
|
||||
}
|
||||
|
||||
const uri = joinPath(this.userDataSyncStoreUrl, 'resource', resource);
|
||||
const uri = joinPath(this.userDataSyncStoreUrl, 'resource', path);
|
||||
const headers: IHeaders = {};
|
||||
|
||||
const context = await this.request(uri.toString(), { type: 'GET', headers }, [], CancellationToken.None);
|
||||
@@ -244,12 +245,12 @@ export class UserDataSyncStoreClient extends Disposable implements IUserDataSync
|
||||
return result.map(({ url, created }) => ({ ref: relativePath(uri, uri.with({ path: url }))!, created: created * 1000 /* Server returns in seconds */ }));
|
||||
}
|
||||
|
||||
async resolveContent(resource: ServerResource, ref: string, headers: IHeaders = {}): Promise<string | null> {
|
||||
async resolveResourceContent(path: string, ref: string, headers: IHeaders = {}): Promise<string | null> {
|
||||
if (!this.userDataSyncStoreUrl) {
|
||||
throw new Error('No settings sync store url configured.');
|
||||
}
|
||||
|
||||
const url = joinPath(this.userDataSyncStoreUrl, 'resource', resource, ref).toString();
|
||||
const url = joinPath(this.userDataSyncStoreUrl, 'resource', path, ref).toString();
|
||||
headers = { ...headers };
|
||||
headers['Cache-Control'] = 'no-cache';
|
||||
|
||||
@@ -258,23 +259,23 @@ export class UserDataSyncStoreClient extends Disposable implements IUserDataSync
|
||||
return content;
|
||||
}
|
||||
|
||||
async delete(resource: ServerResource, ref: string | null): Promise<void> {
|
||||
async deleteResource(path: string, ref: string | null): Promise<void> {
|
||||
if (!this.userDataSyncStoreUrl) {
|
||||
throw new Error('No settings sync store url configured.');
|
||||
}
|
||||
|
||||
const url = ref !== null ? joinPath(this.userDataSyncStoreUrl, 'resource', resource, ref).toString() : joinPath(this.userDataSyncStoreUrl, 'resource', resource).toString();
|
||||
const url = ref !== null ? joinPath(this.userDataSyncStoreUrl, 'resource', path, ref).toString() : joinPath(this.userDataSyncStoreUrl, 'resource', path).toString();
|
||||
const headers: IHeaders = {};
|
||||
|
||||
await this.request(url, { type: 'DELETE', headers }, [], CancellationToken.None);
|
||||
}
|
||||
|
||||
async read(resource: ServerResource, oldValue: IUserData | null, headers: IHeaders = {}): Promise<IUserData> {
|
||||
async readResource(path: string, oldValue: IUserData | null, headers: IHeaders = {}): Promise<IUserData> {
|
||||
if (!this.userDataSyncStoreUrl) {
|
||||
throw new Error('No settings sync store url configured.');
|
||||
}
|
||||
|
||||
const url = joinPath(this.userDataSyncStoreUrl, 'resource', resource, 'latest').toString();
|
||||
const url = joinPath(this.userDataSyncStoreUrl, 'resource', path, 'latest').toString();
|
||||
headers = { ...headers };
|
||||
// Disable caching as they are cached by synchronisers
|
||||
headers['Cache-Control'] = 'no-cache';
|
||||
@@ -306,12 +307,12 @@ export class UserDataSyncStoreClient extends Disposable implements IUserDataSync
|
||||
return userData;
|
||||
}
|
||||
|
||||
async write(resource: ServerResource, data: string, ref: string | null, headers: IHeaders = {}): Promise<string> {
|
||||
async writeResource(path: string, data: string, ref: string | null, headers: IHeaders = {}): Promise<string> {
|
||||
if (!this.userDataSyncStoreUrl) {
|
||||
throw new Error('No settings sync store url configured.');
|
||||
}
|
||||
|
||||
const url = joinPath(this.userDataSyncStoreUrl, 'resource', resource).toString();
|
||||
const url = joinPath(this.userDataSyncStoreUrl, 'resource', path).toString();
|
||||
headers = { ...headers };
|
||||
headers['Content-Type'] = Mimes.text;
|
||||
if (ref) {
|
||||
@@ -549,6 +550,33 @@ export class UserDataSyncStoreService extends UserDataSyncStoreClient implements
|
||||
super(userDataSyncStoreManagementService.userDataSyncStore?.url, productService, requestService, logService, environmentService, fileService, storageService);
|
||||
this._register(userDataSyncStoreManagementService.onDidChangeUserDataSyncStore(() => this.updateUserDataSyncStoreUrl(userDataSyncStoreManagementService.userDataSyncStore?.url)));
|
||||
}
|
||||
|
||||
getAllRefs(resource: ServerResource, profile?: string): Promise<IResourceRefHandle[]> {
|
||||
return this.getAllResourceRefs(profile ? this.getProfileResource(resource, profile) : resource);
|
||||
}
|
||||
|
||||
read(resource: ServerResource, oldValue: IUserData | null, profile?: string, headers?: IHeaders): Promise<IUserData> {
|
||||
return this.readResource(profile ? this.getProfileResource(resource, profile) : resource, oldValue, headers);
|
||||
}
|
||||
|
||||
write(resource: ServerResource, content: string, ref: string | null, profile?: string, headers?: IHeaders): Promise<string> {
|
||||
return this.writeResource(profile ? this.getProfileResource(resource, profile) : resource, content, ref, headers);
|
||||
}
|
||||
|
||||
delete(resource: ServerResource, ref: string | null, profile?: string): Promise<void> {
|
||||
return this.deleteResource(profile ? this.getProfileResource(resource, profile) : resource, ref);
|
||||
}
|
||||
|
||||
resolveContent(resource: ServerResource, ref: string, profile?: string, headers?: IHeaders): Promise<string | null> {
|
||||
return this.resolveResourceContent(profile ? this.getProfileResource(resource, profile) : resource, ref, headers);
|
||||
}
|
||||
|
||||
private getProfileResource(resource: ServerResource, profile: string): string {
|
||||
if (resource === 'profiles') {
|
||||
throw new Error(`Invalid Resource Argument: ${resource}`);
|
||||
}
|
||||
return join('profiles', profile, resource);
|
||||
}
|
||||
}
|
||||
|
||||
export class RequestsSession {
|
||||
|
||||
@@ -77,7 +77,7 @@ export class EditSessionsWorkbenchService extends Disposable implements IEditSes
|
||||
throw new Error('Please sign in to store your edit session.');
|
||||
}
|
||||
|
||||
return this.storeClient!.write('editSessions', JSON.stringify(editSession), null, createSyncHeaders(generateUuid()));
|
||||
return this.storeClient!.writeResource('editSessions', JSON.stringify(editSession), null, createSyncHeaders(generateUuid()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -96,9 +96,9 @@ export class EditSessionsWorkbenchService extends Disposable implements IEditSes
|
||||
const headers = createSyncHeaders(generateUuid());
|
||||
try {
|
||||
if (ref !== undefined) {
|
||||
content = await this.storeClient?.resolveContent('editSessions', ref, headers);
|
||||
content = await this.storeClient?.resolveResourceContent('editSessions', ref, headers);
|
||||
} else {
|
||||
const result = await this.storeClient?.read('editSessions', null, headers);
|
||||
const result = await this.storeClient?.readResource('editSessions', null, headers);
|
||||
content = result?.content;
|
||||
ref = result?.ref;
|
||||
}
|
||||
@@ -117,7 +117,7 @@ export class EditSessionsWorkbenchService extends Disposable implements IEditSes
|
||||
}
|
||||
|
||||
try {
|
||||
await this.storeClient?.delete('editSessions', ref);
|
||||
await this.storeClient?.deleteResource('editSessions', ref);
|
||||
} catch (ex) {
|
||||
this.logService.error(ex);
|
||||
}
|
||||
@@ -130,7 +130,7 @@ export class EditSessionsWorkbenchService extends Disposable implements IEditSes
|
||||
}
|
||||
|
||||
try {
|
||||
return this.storeClient?.getAllRefs('editSessions') ?? [];
|
||||
return this.storeClient?.getAllResourceRefs('editSessions') ?? [];
|
||||
} catch (ex) {
|
||||
this.logService.error(ex);
|
||||
}
|
||||
@@ -400,7 +400,7 @@ export class EditSessionsWorkbenchService extends Disposable implements IEditSes
|
||||
});
|
||||
if (result.confirmed) {
|
||||
if (result.checkboxChecked) {
|
||||
that.storeClient?.delete('editSessions', null);
|
||||
that.storeClient?.deleteResource('editSessions', null);
|
||||
}
|
||||
that.clearAuthenticationPreference();
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ export class RemoteExtensionsInitializerContribution implements IWorkbenchContri
|
||||
|
||||
const userDataSyncStoreClient = this.instantiationService.createInstance(UserDataSyncStoreClient, this.userDataSyncStoreManagementService.userDataSyncStore.url);
|
||||
userDataSyncStoreClient.setAuthToken(session.accessToken, resolvedAuthority.options.authenticationSession.providerId);
|
||||
const userData = await userDataSyncStoreClient.read(SyncResource.Extensions, null);
|
||||
const userData = await userDataSyncStoreClient.readResource(SyncResource.Extensions, null);
|
||||
|
||||
const serviceCollection = new ServiceCollection();
|
||||
serviceCollection.set(IExtensionManagementService, remoteExtensionManagementServer.extensionManagementService);
|
||||
|
||||
@@ -16,7 +16,7 @@ import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { UserDataSyncStoreClient } from 'vs/platform/userDataSync/common/userDataSyncStoreService';
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
import { IRequestService } from 'vs/platform/request/common/request';
|
||||
import { IRemoteUserData, IUserData, IUserDataInitializer, IUserDataSyncLogService, IUserDataSyncStoreClient, IUserDataSyncStoreManagementService, SyncResource } from 'vs/platform/userDataSync/common/userDataSync';
|
||||
import { IRemoteUserData, IUserData, IUserDataInitializer, IUserDataSyncLogService, IUserDataSyncStoreManagementService, SyncResource } from 'vs/platform/userDataSync/common/userDataSync';
|
||||
import { AuthenticationSessionInfo, getCurrentAuthenticationSessionInfo } from 'vs/workbench/services/authentication/browser/authenticationService';
|
||||
import { getSyncAreaLabel } from 'vs/workbench/services/userDataSync/common/userDataSync';
|
||||
import { IWorkbenchContribution, IWorkbenchContributionsRegistry, Extensions } from 'vs/workbench/common/contributions';
|
||||
@@ -77,10 +77,10 @@ export class UserDataInitializationService implements IUserDataInitializationSer
|
||||
});
|
||||
}
|
||||
|
||||
private _userDataSyncStoreClientPromise: Promise<IUserDataSyncStoreClient | undefined> | undefined;
|
||||
private createUserDataSyncStoreClient(): Promise<IUserDataSyncStoreClient | undefined> {
|
||||
private _userDataSyncStoreClientPromise: Promise<UserDataSyncStoreClient | undefined> | undefined;
|
||||
private createUserDataSyncStoreClient(): Promise<UserDataSyncStoreClient | undefined> {
|
||||
if (!this._userDataSyncStoreClientPromise) {
|
||||
this._userDataSyncStoreClientPromise = (async (): Promise<IUserDataSyncStoreClient | undefined> => {
|
||||
this._userDataSyncStoreClientPromise = (async (): Promise<UserDataSyncStoreClient | undefined> => {
|
||||
try {
|
||||
if (!isWeb) {
|
||||
this.logService.trace(`Skipping initializing user data in desktop`);
|
||||
@@ -151,7 +151,7 @@ export class UserDataInitializationService implements IUserDataInitializationSer
|
||||
userDataSyncStoreClient.setAuthToken(authenticationSession.accessToken, authenticationSession.providerId);
|
||||
|
||||
// Cache global state data for global state initialization
|
||||
this.globalStateUserData = await userDataSyncStoreClient.read(SyncResource.GlobalState, null);
|
||||
this.globalStateUserData = await userDataSyncStoreClient.readResource(SyncResource.GlobalState, null);
|
||||
|
||||
if (this.globalStateUserData) {
|
||||
const userDataSyncStoreType = new UserDataSyncStoreTypeSynchronizer(userDataSyncStoreClient, this.storageService, this.environmentService, this.fileService, this.logService).getSyncStoreType(this.globalStateUserData);
|
||||
@@ -238,7 +238,7 @@ export class UserDataInitializationService implements IUserDataInitializationSer
|
||||
if (!userDataSyncStoreClient) {
|
||||
return null;
|
||||
}
|
||||
const userData = await userDataSyncStoreClient.read(SyncResource.Extensions, null);
|
||||
const userData = await userDataSyncStoreClient.readResource(SyncResource.Extensions, null);
|
||||
return instantiationService.createInstance(ExtensionsPreviewInitializer, userData);
|
||||
})();
|
||||
}
|
||||
@@ -260,7 +260,7 @@ export class UserDataInitializationService implements IUserDataInitializationSer
|
||||
this.initialized.push(syncResource);
|
||||
this.logService.trace(`Initializing ${getSyncAreaLabel(syncResource)}`);
|
||||
const initializer = this.createSyncResourceInitializer(syncResource);
|
||||
const userData = await userDataSyncStoreClient.read(syncResource, syncResource === SyncResource.GlobalState ? this.globalStateUserData : null);
|
||||
const userData = await userDataSyncStoreClient.readResource(syncResource, syncResource === SyncResource.GlobalState ? this.globalStateUserData : null);
|
||||
await initializer.initialize(userData);
|
||||
this.logService.info(`Initialized ${getSyncAreaLabel(syncResource)}`);
|
||||
} catch (error) {
|
||||
|
||||
Reference in New Issue
Block a user