Skip to content

Commit 1157e96

Browse files
authored
adopt atomic write for userdata (microsoft#187038)
* microsoft#180695 - adopt atomic write for userdata * check if fsp has atomic write * fix tests
1 parent d58f304 commit 1157e96

File tree

9 files changed

+24
-28
lines changed

9 files changed

+24
-28
lines changed

src/vs/code/electron-main/main.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ import { ILoggerMainService, LoggerMainService } from 'vs/platform/log/electron-
7070
import { LogService } from 'vs/platform/log/common/logService';
7171
import { massageMessageBoxOptions } from 'vs/platform/dialogs/common/dialogs';
7272
import { SaveStrategy, StateService } from 'vs/platform/state/node/stateService';
73+
import { FileUserDataProvider } from 'vs/platform/userData/common/fileUserDataProvider';
7374

7475
/**
7576
* The main VS Code entry point.
@@ -178,6 +179,10 @@ class CodeMain {
178179
const diskFileSystemProvider = new DiskFileSystemProvider(logService);
179180
fileService.registerProvider(Schemas.file, diskFileSystemProvider);
180181

182+
// Use FileUserDataProvider for user data to
183+
// enable atomic read / write operations.
184+
fileService.registerProvider(Schemas.vscodeUserData, new FileUserDataProvider(Schemas.file, diskFileSystemProvider, Schemas.vscodeUserData, logService));
185+
181186
// URI Identity
182187
const uriIdentityService = new UriIdentityService(fileService);
183188
services.set(IUriIdentityService, uriIdentityService);

src/vs/code/node/sharedProcess/sharedProcessMain.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import { DiagnosticsService } from 'vs/platform/diagnostics/node/diagnosticsServ
2626
import { IDownloadService } from 'vs/platform/download/common/download';
2727
import { DownloadService } from 'vs/platform/download/common/downloadService';
2828
import { INativeEnvironmentService } from 'vs/platform/environment/common/environment';
29-
import { SharedProcessEnvironmentService } from 'vs/platform/sharedProcess/node/sharedProcessEnvironmentService';
3029
import { GlobalExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionEnablementService';
3130
import { ExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionGalleryService';
3231
import { IExtensionGalleryService, IExtensionManagementService, IExtensionTipsService, IGlobalExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionManagement';
@@ -112,6 +111,7 @@ import { RemoteStorageService } from 'vs/platform/storage/common/storageService'
112111
import { IRemoteSocketFactoryService, RemoteSocketFactoryService } from 'vs/platform/remote/common/remoteSocketFactoryService';
113112
import { RemoteConnectionType } from 'vs/platform/remote/common/remoteAuthorityResolver';
114113
import { nodeSocketFactory } from 'vs/platform/remote/node/nodeSocketFactory';
114+
import { NativeEnvironmentService } from 'vs/platform/environment/node/environmentService';
115115

116116
class SharedProcessMain extends Disposable {
117117

@@ -191,7 +191,7 @@ class SharedProcessMain extends Disposable {
191191
services.set(IPolicyService, policyService);
192192

193193
// Environment
194-
const environmentService = new SharedProcessEnvironmentService(this.configuration.args, productService);
194+
const environmentService = new NativeEnvironmentService(this.configuration.args, productService);
195195
services.set(INativeEnvironmentService, environmentService);
196196

197197
// Logger

src/vs/platform/environment/common/environmentService.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import { toLocalISOString } from 'vs/base/common/date';
77
import { memoize } from 'vs/base/common/decorators';
8-
import { FileAccess } from 'vs/base/common/network';
8+
import { FileAccess, Schemas } from 'vs/base/common/network';
99
import { dirname, join, normalize, resolve } from 'vs/base/common/path';
1010
import { env } from 'vs/base/common/process';
1111
import { joinPath } from 'vs/base/common/resources';
@@ -65,10 +65,10 @@ export abstract class AbstractNativeEnvironmentService implements INativeEnviron
6565
get stateResource(): URI { return joinPath(this.appSettingsHome, 'globalStorage', 'storage.json'); }
6666

6767
@memoize
68-
get userRoamingDataHome(): URI { return this.appSettingsHome; }
68+
get userRoamingDataHome(): URI { return this.appSettingsHome.with({ scheme: Schemas.vscodeUserData }); }
6969

7070
@memoize
71-
get userDataSyncHome(): URI { return joinPath(this.userRoamingDataHome, 'sync'); }
71+
get userDataSyncHome(): URI { return joinPath(this.appSettingsHome, 'sync'); }
7272

7373
get logsHome(): URI {
7474
if (!this.args.logsPath) {

src/vs/platform/extensionManagement/common/extensionsProfileScannerService.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { URI, UriComponents } from 'vs/base/common/uri';
1212
import { Metadata, isIExtensionIdentifier } from 'vs/platform/extensionManagement/common/extensionManagement';
1313
import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
1414
import { IExtension, IExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
15-
import { FileOperationResult, IFileService, toFileOperationResult } from 'vs/platform/files/common/files';
15+
import { FileOperationResult, IFileService, hasFileAtomicWriteCapability, toFileOperationResult } from 'vs/platform/files/common/files';
1616
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
1717
import { ILogService } from 'vs/platform/log/common/log';
1818
import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile';
@@ -290,7 +290,8 @@ export abstract class AbstractExtensionsProfileScannerService extends Disposable
290290
relativeLocation: this.toRelativePath(e.location),
291291
metadata: e.metadata
292292
}));
293-
await this.fileService.writeFile(file, VSBuffer.fromString(JSON.stringify(storedProfileExtensions)));
293+
const fsp = this.fileService.getProvider(file.scheme);
294+
await this.fileService.writeFile(file, VSBuffer.fromString(JSON.stringify(storedProfileExtensions)), fsp && hasFileAtomicWriteCapability(fsp) ? { atomic: { postfix: '.vsctmp' } } : undefined);
294295
}
295296

296297
return extensions;

src/vs/platform/sharedProcess/node/sharedProcessEnvironmentService.ts

Lines changed: 0 additions & 16 deletions
This file was deleted.

src/vs/platform/userData/common/fileUserDataProvider.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,14 @@
44
*--------------------------------------------------------------------------------------------*/
55
import { Event, Emitter } from 'vs/base/common/event';
66
import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
7-
import { IFileSystemProviderWithFileReadWriteCapability, IFileChange, IWatchOptions, IStat, IFileOverwriteOptions, FileType, IFileWriteOptions, IFileDeleteOptions, FileSystemProviderCapabilities, IFileSystemProviderWithFileReadStreamCapability, IFileReadStreamOptions, IFileSystemProviderWithFileAtomicReadCapability, IFileSystemProviderWithFileFolderCopyCapability, hasFileFolderCopyCapability } from 'vs/platform/files/common/files';
7+
import { IFileSystemProviderWithFileReadWriteCapability, IFileChange, IWatchOptions, IStat, IFileOverwriteOptions, FileType, IFileWriteOptions, IFileDeleteOptions, FileSystemProviderCapabilities, IFileSystemProviderWithFileReadStreamCapability, IFileReadStreamOptions, IFileSystemProviderWithFileAtomicReadCapability, IFileSystemProviderWithFileFolderCopyCapability, hasFileFolderCopyCapability, hasFileAtomicWriteCapability } from 'vs/platform/files/common/files';
88
import { URI } from 'vs/base/common/uri';
99
import { CancellationToken } from 'vs/base/common/cancellation';
1010
import { newWriteableStream, ReadableStreamEvents } from 'vs/base/common/stream';
1111
import { ILogService } from 'vs/platform/log/common/log';
1212
import { TernarySearchTree } from 'vs/base/common/ternarySearchTree';
1313
import { VSBuffer } from 'vs/base/common/buffer';
14+
import { isObject } from 'vs/base/common/types';
1415

1516
/**
1617
* This is a wrapper on top of the local filesystem provider which will
@@ -85,6 +86,9 @@ export class FileUserDataProvider extends Disposable implements
8586
}
8687

8788
writeFile(resource: URI, content: Uint8Array, opts: IFileWriteOptions): Promise<void> {
89+
if (!isObject(opts.atomic) && hasFileAtomicWriteCapability(this.fileSystemProvider)) {
90+
opts = { ...opts, atomic: { postfix: '.vsctmp' } };
91+
}
8892
return this.fileSystemProvider.writeFile(this.toFileSystemResource(resource), content, opts);
8993
}
9094

src/vs/server/node/serverEnvironmentService.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import { NativeEnvironmentService } from 'vs/platform/environment/node/environme
99
import { OPTIONS, OptionDescriptions } from 'vs/platform/environment/node/argv';
1010
import { refineServiceDecorator } from 'vs/platform/instantiation/common/instantiation';
1111
import { IEnvironmentService, INativeEnvironmentService } from 'vs/platform/environment/common/environment';
12+
import { memoize } from 'vs/base/common/decorators';
13+
import { URI } from 'vs/base/common/uri';
1214

1315
export const serverOptions: OptionDescriptions<Required<ServerParsedArgs>> = {
1416

@@ -211,5 +213,7 @@ export interface IServerEnvironmentService extends INativeEnvironmentService {
211213
}
212214

213215
export class ServerEnvironmentService extends NativeEnvironmentService implements IServerEnvironmentService {
216+
@memoize
217+
override get userRoamingDataHome(): URI { return this.appSettingsHome; }
214218
override get args(): ServerParsedArgs { return super.args as ServerParsedArgs; }
215219
}

src/vs/workbench/electron-sandbox/desktop.main.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,8 @@ export class DesktopMain extends Disposable {
224224
const diskFileSystemProvider = this._register(new DiskFileSystemProvider(mainProcessService, utilityProcessWorkerWorkbenchService, logService));
225225
fileService.registerProvider(Schemas.file, diskFileSystemProvider);
226226

227-
// User Data Provider
227+
// Use FileUserDataProvider for user data to
228+
// enable atomic read / write operations.
228229
fileService.registerProvider(Schemas.vscodeUserData, this._register(new FileUserDataProvider(Schemas.file, diskFileSystemProvider, Schemas.vscodeUserData, logService)));
229230

230231
// URI Identity

src/vs/workbench/services/environment/electron-sandbox/environmentService.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,6 @@ export class NativeWorkbenchEnvironmentService extends AbstractNativeEnvironment
8484
};
8585
}
8686

87-
@memoize
88-
override get userRoamingDataHome(): URI { return this.appSettingsHome.with({ scheme: Schemas.vscodeUserData }); }
89-
9087
@memoize
9188
get windowLogsPath(): URI { return joinPath(this.logsHome, `window${this.configuration.windowId}`); }
9289

0 commit comments

Comments
 (0)