mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-27 03:54:24 +01:00
Move user data sync to shared process
This commit is contained in:
|
Before Width: | Height: | Size: 481 B After Width: | Height: | Size: 481 B |
|
Before Width: | Height: | Size: 481 B After Width: | Height: | Size: 481 B |
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions, IWorkbenchContribution } from 'vs/workbench/common/contributions';
|
||||
import { IUserDataSyncService, SyncStatus, USER_DATA_PREVIEW_SCHEME } from 'vs/platform/userDataSync/common/userDataSync';
|
||||
import { IUserDataSyncService, SyncStatus, SyncSource } 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';
|
||||
@@ -16,7 +16,6 @@ import { MenuRegistry, MenuId, IMenuItem } from 'vs/platform/actions/common/acti
|
||||
import { RawContextKey, IContextKeyService, IContextKey, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { IActivityService, IBadge, NumberBadge, ProgressBadge } from 'vs/workbench/services/activity/common/activity';
|
||||
import { GLOBAL_ACTIVITY_ID } from 'vs/workbench/common/activity';
|
||||
import { timeout } from 'vs/base/common/async';
|
||||
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { registerAndGetAmdImageURL } from 'vs/base/common/amd';
|
||||
@@ -25,8 +24,8 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic
|
||||
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { IHistoryService } from 'vs/workbench/services/history/common/history';
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { InMemoryFileSystemProvider } from 'vs/workbench/services/userData/common/inMemoryUserDataProvider';
|
||||
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
||||
import { isEqual } from 'vs/base/common/resources';
|
||||
|
||||
const CONTEXT_SYNC_STATE = new RawContextKey<string>('syncStatus', SyncStatus.Uninitialized);
|
||||
|
||||
@@ -46,39 +45,6 @@ Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration)
|
||||
}
|
||||
});
|
||||
|
||||
class UserDataSyncContribution extends Disposable implements IWorkbenchContribution {
|
||||
|
||||
constructor(
|
||||
@IFileService fileService: IFileService,
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService,
|
||||
@IUserDataSyncService private readonly userDataSyncService: IUserDataSyncService,
|
||||
) {
|
||||
super();
|
||||
this._register(fileService.registerProvider(USER_DATA_PREVIEW_SCHEME, new InMemoryFileSystemProvider()));
|
||||
this.sync(true);
|
||||
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')) {
|
||||
try {
|
||||
await this.userDataSyncService.sync();
|
||||
} catch (e) {
|
||||
// Ignore errors
|
||||
}
|
||||
if (loop) {
|
||||
await timeout(1000 * 5); // Loop sync for every 5s.
|
||||
this.sync(loop);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const SYNC_PUSH_LIGHT_ICON_URI = URI.parse(registerAndGetAmdImageURL(`vs/workbench/contrib/userData/browser/media/sync-push-light.svg`));
|
||||
const SYNC_PUSH_DARK_ICON_URI = URI.parse(registerAndGetAmdImageURL(`vs/workbench/contrib/userData/browser/media/sync-push-dark.svg`));
|
||||
class SyncActionsContribution extends Disposable implements IWorkbenchContribution {
|
||||
@@ -96,6 +62,7 @@ class SyncActionsContribution extends Disposable implements IWorkbenchContributi
|
||||
@IEditorService private readonly editorService: IEditorService,
|
||||
@ITextFileService private readonly textFileService: ITextFileService,
|
||||
@IHistoryService private readonly historyService: IHistoryService,
|
||||
@IWorkbenchEnvironmentService private readonly workbenchEnvironmentService: IWorkbenchEnvironmentService,
|
||||
) {
|
||||
super();
|
||||
this.syncEnablementContext = CONTEXT_SYNC_STATE.bindTo(contextKeyService);
|
||||
@@ -142,17 +109,14 @@ class SyncActionsContribution extends Disposable implements IWorkbenchContributi
|
||||
|
||||
private async continueSync(): Promise<void> {
|
||||
// Get the preview editor
|
||||
const editorInput = this.editorService.editors.filter(input => {
|
||||
const resource = input.getResource();
|
||||
return resource && resource.scheme === USER_DATA_PREVIEW_SCHEME;
|
||||
})[0];
|
||||
const editorInput = this.editorService.editors.filter(input => isEqual(input.getResource(), this.workbenchEnvironmentService.settingsSyncPreviewResource))[0];
|
||||
// Save the preview
|
||||
if (editorInput && editorInput.isDirty()) {
|
||||
await this.textFileService.save(editorInput.getResource()!);
|
||||
}
|
||||
try {
|
||||
// Continue Sync
|
||||
await this.userDataSyncService.continueSync();
|
||||
await this.userDataSyncService.sync(true);
|
||||
} catch (error) {
|
||||
this.notificationService.error(error);
|
||||
return;
|
||||
@@ -164,10 +128,9 @@ class SyncActionsContribution extends Disposable implements IWorkbenchContributi
|
||||
}
|
||||
|
||||
private async handleConflicts(): Promise<void> {
|
||||
const resource = this.userDataSyncService.conflicts;
|
||||
if (resource) {
|
||||
if (this.userDataSyncService.conflictsSource === SyncSource.Settings ) {
|
||||
const resourceInput = {
|
||||
resource,
|
||||
resource: this.workbenchEnvironmentService.settingsSyncPreviewResource,
|
||||
options: {
|
||||
preserveFocus: false,
|
||||
pinned: false,
|
||||
@@ -237,11 +200,10 @@ class SyncActionsContribution extends Disposable implements IWorkbenchContributi
|
||||
},
|
||||
group: 'navigation',
|
||||
order: 1,
|
||||
when: ContextKeyExpr.and(CONTEXT_SYNC_STATE.isEqualTo(SyncStatus.HasConflicts), ResourceContextKey.Scheme.isEqualTo(USER_DATA_PREVIEW_SCHEME)),
|
||||
when: ContextKeyExpr.and(CONTEXT_SYNC_STATE.isEqualTo(SyncStatus.HasConflicts), ResourceContextKey.Resource.isEqualTo(this.workbenchEnvironmentService.settingsSyncPreviewResource.toString())),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const workbenchRegistry = Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench);
|
||||
workbenchRegistry.registerWorkbenchContribution(SyncActionsContribution, LifecyclePhase.Starting);
|
||||
workbenchRegistry.registerWorkbenchContribution(UserDataSyncContribution, LifecyclePhase.Eventually);
|
||||
@@ -0,0 +1,24 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions, IWorkbenchContribution } from 'vs/workbench/common/contributions';
|
||||
import { ISettingsMergeService } from 'vs/platform/userDataSync/common/userDataSync';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
|
||||
import { ISharedProcessService } from 'vs/platform/ipc/electron-browser/sharedProcessService';
|
||||
import { SettingsMergeChannel } from 'vs/platform/userDataSync/common/settingsSyncIpc';
|
||||
|
||||
class UserDataSyncServicesContribution implements IWorkbenchContribution {
|
||||
|
||||
constructor(
|
||||
@ISettingsMergeService settingsMergeService: ISettingsMergeService,
|
||||
@ISharedProcessService sharedProcessService: ISharedProcessService,
|
||||
) {
|
||||
sharedProcessService.registerChannel('settingsMerge', new SettingsMergeChannel(settingsMergeService));
|
||||
}
|
||||
}
|
||||
|
||||
const workbenchRegistry = Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench);
|
||||
workbenchRegistry.registerWorkbenchContribution(UserDataSyncServicesContribution, LifecyclePhase.Starting);
|
||||
@@ -84,6 +84,7 @@ export class BrowserWorkbenchEnvironmentService implements IWorkbenchEnvironment
|
||||
this.configuration.machineId = generateUuid();
|
||||
this.userRoamingDataHome = URI.file('/User').with({ scheme: Schemas.userData });
|
||||
this.settingsResource = joinPath(this.userRoamingDataHome, 'settings.json');
|
||||
this.settingsSyncPreviewResource = joinPath(this.userRoamingDataHome, '.settings.json');
|
||||
this.keybindingsResource = joinPath(this.userRoamingDataHome, 'keybindings.json');
|
||||
this.keyboardLayoutResource = joinPath(this.userRoamingDataHome, 'keyboardLayout.json');
|
||||
this.localeResource = joinPath(this.userRoamingDataHome, 'locale.json');
|
||||
@@ -141,6 +142,7 @@ export class BrowserWorkbenchEnvironmentService implements IWorkbenchEnvironment
|
||||
appSettingsHome: URI;
|
||||
userRoamingDataHome: URI;
|
||||
settingsResource: URI;
|
||||
settingsSyncPreviewResource: URI;
|
||||
keybindingsResource: URI;
|
||||
keyboardLayoutResource: URI;
|
||||
localeResource: URI;
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { SyncStatus, SyncSource, IUserDataSyncService } from 'vs/platform/userDataSync/common/userDataSync';
|
||||
import { ISharedProcessService } from 'vs/platform/ipc/electron-browser/sharedProcessService';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { IChannel } from 'vs/base/parts/ipc/common/ipc';
|
||||
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
||||
|
||||
export class UserDataSyncService extends Disposable implements IUserDataSyncService {
|
||||
|
||||
_serviceBrand: undefined;
|
||||
|
||||
private readonly channel: IChannel;
|
||||
|
||||
private _status: SyncStatus = SyncStatus.Uninitialized;
|
||||
get status(): SyncStatus { return this._status; }
|
||||
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'); }
|
||||
|
||||
private _conflictsSource: SyncSource | null = null;
|
||||
get conflictsSource(): SyncSource | null { return this._conflictsSource; }
|
||||
|
||||
constructor(
|
||||
@ISharedProcessService sharedProcessService: ISharedProcessService
|
||||
) {
|
||||
super();
|
||||
this.channel = sharedProcessService.getChannel('userDataSync');
|
||||
this._register(this.channel.listen<SyncStatus>('onDidChangeStatus')(status => this.updateStatus(status)));
|
||||
}
|
||||
|
||||
sync(_continue?: boolean): Promise<boolean> {
|
||||
return this.channel.call('sync', [_continue]);
|
||||
}
|
||||
|
||||
private async updateStatus(status: SyncStatus): Promise<void> {
|
||||
this._conflictsSource = await this.channel.call<SyncSource>('getConflictsSource');
|
||||
this._status = status;
|
||||
this._onDidChangeStatus.fire(status);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
registerSingleton(IUserDataSyncService, UserDataSyncService);
|
||||
@@ -79,7 +79,7 @@ import 'vs/workbench/services/label/common/labelService';
|
||||
import 'vs/workbench/services/extensionManagement/common/extensionEnablementService';
|
||||
import 'vs/workbench/services/notification/common/notificationService';
|
||||
import 'vs/workbench/services/extensions/common/staticExtensions';
|
||||
import 'vs/workbench/services/userData/common/settingsMergeService';
|
||||
import 'vs/workbench/services/userDataSync/common/settingsMergeService';
|
||||
import 'vs/workbench/services/workspace/browser/workspaceEditingService';
|
||||
|
||||
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
||||
@@ -106,9 +106,6 @@ import { IDownloadService } from 'vs/platform/download/common/download';
|
||||
import { DownloadService } from 'vs/platform/download/common/downloadService';
|
||||
import { OpenerService } from 'vs/editor/browser/services/openerService';
|
||||
import { IOpenerService } from 'vs/platform/opener/common/opener';
|
||||
import { IUserDataSyncStoreService, IUserDataSyncService } from 'vs/platform/userDataSync/common/userDataSync';
|
||||
import { UserDataSyncStoreService } from 'vs/platform/userDataSync/common/userDataSyncStoreService';
|
||||
import { UserDataSyncService } from 'vs/platform/userDataSync/common/userDataSyncService';
|
||||
|
||||
registerSingleton(IExtensionGalleryService, ExtensionGalleryService, true);
|
||||
registerSingleton(IContextViewService, ContextViewService, true);
|
||||
@@ -122,8 +119,6 @@ registerSingleton(ITextResourceConfigurationService, TextResourceConfigurationSe
|
||||
registerSingleton(IMenuService, MenuService, true);
|
||||
registerSingleton(IDownloadService, DownloadService, true);
|
||||
registerSingleton(IOpenerService, OpenerService, true);
|
||||
registerSingleton(IUserDataSyncStoreService, UserDataSyncStoreService);
|
||||
registerSingleton(IUserDataSyncService, UserDataSyncService);
|
||||
|
||||
//#endregion
|
||||
|
||||
@@ -259,7 +254,7 @@ import 'vs/workbench/contrib/experiments/browser/experiments.contribution';
|
||||
// Send a Smile
|
||||
import 'vs/workbench/contrib/feedback/browser/feedback.contribution';
|
||||
|
||||
// User Data
|
||||
import 'vs/workbench/contrib/userData/browser/userData.contribution';
|
||||
// User Data Sync
|
||||
import 'vs/workbench/contrib/userDataSync/browser/userDataSync.contribution';
|
||||
|
||||
//#endregion
|
||||
|
||||
@@ -49,6 +49,7 @@ import 'vs/workbench/services/backup/node/backupFileService';
|
||||
import 'vs/workbench/services/credentials/node/credentialsService';
|
||||
import 'vs/workbench/services/url/electron-browser/urlService';
|
||||
import 'vs/workbench/services/workspace/electron-browser/workspacesService';
|
||||
import 'vs/workbench/services/userDataSync/electron-browser/userDataSyncService';
|
||||
|
||||
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
||||
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
|
||||
@@ -137,4 +138,7 @@ import 'vs/workbench/contrib/issue/electron-browser/issue.contribution';
|
||||
// Tasks
|
||||
import 'vs/workbench/contrib/tasks/electron-browser/taskService';
|
||||
|
||||
// User Data Sync
|
||||
import 'vs/workbench/contrib/userDataSync/electron-browser/userDataSync.contribution';
|
||||
|
||||
//#endregion
|
||||
|
||||
@@ -61,6 +61,9 @@ import { BackupFileService } from 'vs/workbench/services/backup/common/backupFil
|
||||
import { ExtensionManagementService } from 'vs/workbench/services/extensionManagement/common/extensionManagementService';
|
||||
import { ITunnelService } from 'vs/platform/remote/common/tunnel';
|
||||
import { NoOpTunnelService } from 'vs/platform/remote/common/tunnelService';
|
||||
import { IUserDataSyncStoreService, IUserDataSyncService } from 'vs/platform/userDataSync/common/userDataSync';
|
||||
import { UserDataSyncStoreService } from 'vs/platform/userDataSync/common/userDataSyncStoreService';
|
||||
import { UserDataSyncService } from 'vs/platform/userDataSync/common/userDataSyncService';
|
||||
|
||||
registerSingleton(IRequestService, RequestService, true);
|
||||
registerSingleton(IExtensionManagementService, ExtensionManagementService);
|
||||
@@ -70,6 +73,8 @@ registerSingleton(IAccessibilityService, BrowserAccessibilityService, true);
|
||||
registerSingleton(ILifecycleService, BrowserLifecycleService);
|
||||
registerSingleton(IContextMenuService, ContextMenuService);
|
||||
registerSingleton(ITunnelService, NoOpTunnelService, true);
|
||||
registerSingleton(IUserDataSyncStoreService, UserDataSyncStoreService);
|
||||
registerSingleton(IUserDataSyncService, UserDataSyncService);
|
||||
|
||||
//#endregion
|
||||
|
||||
|
||||
Reference in New Issue
Block a user