Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
sandy081 authored Sep 14, 2023
1 parent b2abe1b commit 3b60c12
Show file tree
Hide file tree
Showing 11 changed files with 76 additions and 39 deletions.
8 changes: 4 additions & 4 deletions src/vs/code/electron-main/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,10 +179,6 @@ class CodeMain {
const diskFileSystemProvider = new DiskFileSystemProvider(logService);
fileService.registerProvider(Schemas.file, diskFileSystemProvider);

// Use FileUserDataProvider for user data to
// enable atomic read / write operations.
fileService.registerProvider(Schemas.vscodeUserData, new FileUserDataProvider(Schemas.file, diskFileSystemProvider, Schemas.vscodeUserData, logService));

// URI Identity
const uriIdentityService = new UriIdentityService(fileService);
services.set(IUriIdentityService, uriIdentityService);
Expand All @@ -196,6 +192,10 @@ class CodeMain {
const userDataProfilesMainService = new UserDataProfilesMainService(stateService, uriIdentityService, environmentMainService, fileService, logService);
services.set(IUserDataProfilesMainService, userDataProfilesMainService);

// Use FileUserDataProvider for user data to
// enable atomic read / write operations.
fileService.registerProvider(Schemas.vscodeUserData, new FileUserDataProvider(Schemas.file, diskFileSystemProvider, Schemas.vscodeUserData, userDataProfilesMainService, uriIdentityService, logService));

// Policy
const policyService = isWindows && productService.win32RegValueName ? disposables.add(new NativePolicyService(logService, productService.win32RegValueName))
: environmentMainService.policyFile ? disposables.add(new FilePolicyService(environmentMainService.policyFile, fileService, logService))
Expand Down
8 changes: 4 additions & 4 deletions src/vs/code/node/cliProcessMain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,10 +146,6 @@ class CliMain extends Disposable {
const diskFileSystemProvider = this._register(new DiskFileSystemProvider(logService));
fileService.registerProvider(Schemas.file, diskFileSystemProvider);

// Use FileUserDataProvider for user data to
// enable atomic read / write operations.
fileService.registerProvider(Schemas.vscodeUserData, new FileUserDataProvider(Schemas.file, diskFileSystemProvider, Schemas.vscodeUserData, logService));

// Uri Identity
const uriIdentityService = new UriIdentityService(fileService);
services.set(IUriIdentityService, uriIdentityService);
Expand All @@ -159,6 +155,10 @@ class CliMain extends Disposable {
const userDataProfilesService = new UserDataProfilesReadonlyService(stateService, uriIdentityService, environmentService, fileService, logService);
services.set(IUserDataProfilesService, userDataProfilesService);

// Use FileUserDataProvider for user data to
// enable atomic read / write operations.
fileService.registerProvider(Schemas.vscodeUserData, new FileUserDataProvider(Schemas.file, diskFileSystemProvider, Schemas.vscodeUserData, userDataProfilesService, uriIdentityService, logService));

// Policy
const policyService = isWindows && productService.win32RegValueName ? this._register(new NativePolicyService(logService, productService.win32RegValueName))
: environmentService.policyFile ? this._register(new FilePolicyService(environmentService.policyFile, fileService, logService))
Expand Down
18 changes: 10 additions & 8 deletions src/vs/code/node/sharedProcess/sharedProcessMain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,14 @@ class SharedProcessMain extends Disposable implements IClientConnectionFilter {
const diskFileSystemProvider = this._register(new DiskFileSystemProvider(logService));
fileService.registerProvider(Schemas.file, diskFileSystemProvider);

// URI Identity
const uriIdentityService = new UriIdentityService(fileService);
services.set(IUriIdentityService, uriIdentityService);

// User Data Profiles
const userDataProfilesService = this._register(new UserDataProfilesService(this.configuration.profiles.all, URI.revive(this.configuration.profiles.home).with({ scheme: environmentService.userRoamingDataHome.scheme }), mainProcessService.getChannel('userDataProfiles')));
services.set(IUserDataProfilesService, userDataProfilesService);

const userDataFileSystemProvider = this._register(new FileUserDataProvider(
Schemas.file,
// Specifically for user data, use the disk file system provider
Expand All @@ -231,14 +239,12 @@ class SharedProcessMain extends Disposable implements IClientConnectionFilter {
// processes, we want a single process handling these operations.
this._register(new DiskFileSystemProviderClient(mainProcessService.getChannel(LOCAL_FILE_SYSTEM_CHANNEL_NAME), { pathCaseSensitive: isLinux })),
Schemas.vscodeUserData,
userDataProfilesService,
uriIdentityService,
logService
));
fileService.registerProvider(Schemas.vscodeUserData, userDataFileSystemProvider);

// User Data Profiles
const userDataProfilesService = this._register(new UserDataProfilesService(this.configuration.profiles.all, URI.revive(this.configuration.profiles.home).with({ scheme: environmentService.userRoamingDataHome.scheme }), mainProcessService.getChannel('userDataProfiles')));
services.set(IUserDataProfilesService, userDataProfilesService);

// Configuration
const configurationService = this._register(new ConfigurationService(userDataProfilesService.defaultProfile.settingsResource, fileService, policyService, logService));
services.set(IConfigurationService, configurationService);
Expand All @@ -254,10 +260,6 @@ class SharedProcessMain extends Disposable implements IClientConnectionFilter {
storageService.initialize()
]);

// URI Identity
const uriIdentityService = new UriIdentityService(fileService);
services.set(IUriIdentityService, uriIdentityService);

// Request
const requestService = new RequestChannelClient(mainProcessService.getChannel('request'));
services.set(IRequestService, requestService);
Expand Down
21 changes: 20 additions & 1 deletion src/vs/platform/userData/common/fileUserDataProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ import { ILogService } from 'vs/platform/log/common/log';
import { TernarySearchTree } from 'vs/base/common/ternarySearchTree';
import { VSBuffer } from 'vs/base/common/buffer';
import { isObject } from 'vs/base/common/types';
import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile';
import { ResourceSet } from 'vs/base/common/map';
import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity';

/**
* This is a wrapper on top of the local filesystem provider which will
Expand All @@ -31,17 +34,33 @@ export class FileUserDataProvider extends Disposable implements
readonly onDidChangeFile: Event<readonly IFileChange[]> = this._onDidChangeFile.event;

private readonly watchResources = TernarySearchTree.forUris<URI>(() => !(this.capabilities & FileSystemProviderCapabilities.PathCaseSensitive));
private readonly atomicWritesResources: ResourceSet;

constructor(
private readonly fileSystemScheme: string,
private readonly fileSystemProvider: IFileSystemProviderWithFileReadWriteCapability & (IFileSystemProviderWithFileReadStreamCapability | IFileSystemProviderWithFileAtomicReadCapability | IFileSystemProviderWithFileFolderCopyCapability),
private readonly userDataScheme: string,
private readonly userDataProfilesService: IUserDataProfilesService,
uriIdentityService: IUriIdentityService,
private readonly logService: ILogService,
) {
super();
this.atomicWritesResources = new ResourceSet((uri) => uriIdentityService.extUri.getComparisonKey(this.toFileSystemResource(uri)));
this.updateAtomicWritesResources();
this._register(userDataProfilesService.onDidChangeProfiles(() => this.updateAtomicWritesResources()));
this._register(this.fileSystemProvider.onDidChangeFile(e => this.handleFileChanges(e)));
}

private updateAtomicWritesResources(): void {
this.atomicWritesResources.clear();
for (const profile of this.userDataProfilesService.profiles) {
this.atomicWritesResources.add(profile.settingsResource);
this.atomicWritesResources.add(profile.keybindingsResource);
this.atomicWritesResources.add(profile.tasksResource);
this.atomicWritesResources.add(profile.extensionsResource);
}
}

watch(resource: URI, opts: IWatchOptions): IDisposable {
this.watchResources.set(resource, resource);
const disposable = this.fileSystemProvider.watch(this.toFileSystemResource(resource), opts);
Expand Down Expand Up @@ -86,7 +105,7 @@ export class FileUserDataProvider extends Disposable implements
}

writeFile(resource: URI, content: Uint8Array, opts: IFileWriteOptions): Promise<void> {
if (!isObject(opts.atomic) && hasFileAtomicWriteCapability(this.fileSystemProvider)) {
if (this.atomicWritesResources.has(resource) && !isObject(opts.atomic) && hasFileAtomicWriteCapability(this.fileSystemProvider)) {
opts = { ...opts, atomic: { postfix: '.vsctmp' } };
}
return this.fileSystemProvider.writeFile(this.toFileSystemResource(resource), content, opts);
Expand Down
13 changes: 10 additions & 3 deletions src/vs/platform/userData/test/browser/fileUserDataProvider.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,10 @@ suite('FileUserDataProvider', () => {
await testObject.createFolder(backupWorkspaceHomeOnDisk);

environmentService = new TestEnvironmentService(userDataHomeOnDisk);
userDataProfilesService = disposables.add(new UserDataProfilesService(environmentService, testObject, disposables.add(new UriIdentityService(testObject)), logService));
const uriIdentityService = disposables.add(new UriIdentityService(testObject));
userDataProfilesService = disposables.add(new UserDataProfilesService(environmentService, testObject, uriIdentityService, logService));

fileUserDataProvider = disposables.add(new FileUserDataProvider(ROOT.scheme, fileSystemProvider, Schemas.vscodeUserData, logService));
fileUserDataProvider = disposables.add(new FileUserDataProvider(ROOT.scheme, fileSystemProvider, Schemas.vscodeUserData, userDataProfilesService, uriIdentityService, logService));
disposables.add(fileUserDataProvider);
disposables.add(testObject.registerProvider(Schemas.vscodeUserData, fileUserDataProvider));
});
Expand Down Expand Up @@ -313,8 +314,14 @@ suite('FileUserDataProvider - Watching', () => {
let fileEventEmitter: Emitter<readonly IFileChange[]>;

setup(() => {
const logService = new NullLogService();
const fileService = disposables.add(new FileService(logService));
const environmentService = new TestEnvironmentService(rootFileResource);
const uriIdentityService = disposables.add(new UriIdentityService(fileService));
const userDataProfilesService = disposables.add(new UserDataProfilesService(environmentService, fileService, uriIdentityService, logService));

fileEventEmitter = disposables.add(new Emitter<readonly IFileChange[]>());
testObject = disposables.add(new FileUserDataProvider(rootFileResource.scheme, new TestFileSystemProvider(fileEventEmitter.event), Schemas.vscodeUserData, new NullLogService()));
testObject = disposables.add(new FileUserDataProvider(rootFileResource.scheme, new TestFileSystemProvider(fileEventEmitter.event), Schemas.vscodeUserData, userDataProfilesService, uriIdentityService, new NullLogService()));
});

teardown(() => disposables.clear());
Expand Down
8 changes: 4 additions & 4 deletions src/vs/workbench/electron-sandbox/desktop.main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,10 +237,6 @@ export class DesktopMain extends Disposable {
const diskFileSystemProvider = this._register(new DiskFileSystemProvider(mainProcessService, utilityProcessWorkerWorkbenchService, logService));
fileService.registerProvider(Schemas.file, diskFileSystemProvider);

// Use FileUserDataProvider for user data to
// enable atomic read / write operations.
fileService.registerProvider(Schemas.vscodeUserData, this._register(new FileUserDataProvider(Schemas.file, diskFileSystemProvider, Schemas.vscodeUserData, logService)));

// URI Identity
const uriIdentityService = new UriIdentityService(fileService);
serviceCollection.set(IUriIdentityService, uriIdentityService);
Expand All @@ -251,6 +247,10 @@ export class DesktopMain extends Disposable {
const userDataProfileService = new UserDataProfileService(reviveProfile(this.configuration.profiles.profile, userDataProfilesService.profilesHome.scheme));
serviceCollection.set(IUserDataProfileService, userDataProfileService);

// Use FileUserDataProvider for user data to
// enable atomic read / write operations.
fileService.registerProvider(Schemas.vscodeUserData, this._register(new FileUserDataProvider(Schemas.file, diskFileSystemProvider, Schemas.vscodeUserData, userDataProfilesService, uriIdentityService, logService)));

// Remote Agent
const remoteSocketFactoryService = new RemoteSocketFactoryService();
remoteSocketFactoryService.register(RemoteConnectionType.WebSocket, new BrowserSocketFactory(null));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ suite('ConfigurationEditing', () => {
const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, uriIdentityService, logService));
userDataProfileService = new UserDataProfileService(userDataProfilesService.defaultProfile);
const remoteAgentService = disposables.add(instantiationService.createInstance(RemoteAgentService));
disposables.add(fileService.registerProvider(Schemas.vscodeUserData, disposables.add(new FileUserDataProvider(ROOT.scheme, fileSystemProvider, Schemas.vscodeUserData, logService))));
disposables.add(fileService.registerProvider(Schemas.vscodeUserData, disposables.add(new FileUserDataProvider(ROOT.scheme, fileSystemProvider, Schemas.vscodeUserData, userDataProfilesService, uriIdentityService, logService))));
instantiationService.stub(IFileService, fileService);
instantiationService.stub(IRemoteAgentService, remoteAgentService);
workspaceService = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, userDataProfileService, userDataProfilesService, fileService, remoteAgentService, uriIdentityService, new NullLogService(), new FilePolicyService(environmentService.policyFile, fileService, logService)));
Expand Down
Loading

0 comments on commit 3b60c12

Please sign in to comment.