diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index 2942951649663..14f282ce40652 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -1141,7 +1141,7 @@ export class CodeApplication extends Disposable { // Local Files const diskFileSystemProvider = this.fileService.getProvider(Schemas.file); assertType(diskFileSystemProvider instanceof DiskFileSystemProvider); - const fileSystemProviderChannel = disposables.add(new DiskFileSystemProviderChannel(diskFileSystemProvider, this.logService, this.environmentMainService)); + const fileSystemProviderChannel = disposables.add(new DiskFileSystemProviderChannel(diskFileSystemProvider, this.logService, this.environmentMainService, this.configurationService)); mainProcessElectronServer.registerChannel(LOCAL_FILE_SYSTEM_CHANNEL_NAME, fileSystemProviderChannel); sharedProcessClient.then(client => client.registerChannel(LOCAL_FILE_SYSTEM_CHANNEL_NAME, fileSystemProviderChannel)); diff --git a/src/vs/platform/files/common/diskFileSystemProvider.ts b/src/vs/platform/files/common/diskFileSystemProvider.ts index 5b3ee2b8bf279..341d3fa32f164 100644 --- a/src/vs/platform/files/common/diskFileSystemProvider.ts +++ b/src/vs/platform/files/common/diskFileSystemProvider.ts @@ -44,7 +44,7 @@ export abstract class AbstractDiskFileSystemProvider extends Disposable implemen constructor( protected readonly logService: ILogService, - private readonly options?: IDiskFileSystemProviderOptions + protected options?: IDiskFileSystemProviderOptions ) { super(); } @@ -71,16 +71,7 @@ export abstract class AbstractDiskFileSystemProvider extends Disposable implemen private readonly universalWatchRequestDelayer = this._register(new ThrottledDelayer(0)); private watchUniversal(resource: URI, opts: IWatchOptions): IDisposable { - - // Add to list of paths to watch universally - const request: IUniversalWatchRequest = { - path: this.toWatchPath(resource), - excludes: opts.excludes, - includes: opts.includes, - recursive: opts.recursive, - filter: opts.filter, - correlationId: opts.correlationId - }; + const request = this.toWatchRequest(resource, opts); const remove = insert(this.universalWatchRequests, request); // Trigger update @@ -96,6 +87,37 @@ export abstract class AbstractDiskFileSystemProvider extends Disposable implemen }); } + private toWatchRequest(resource: URI, opts: IWatchOptions): IUniversalWatchRequest { + const request: IUniversalWatchRequest = { + path: this.toWatchPath(resource), + excludes: opts.excludes, + includes: opts.includes, + recursive: opts.recursive, + filter: opts.filter, + correlationId: opts.correlationId + }; + + if (isRecursiveWatchRequest(request)) { + + // Adjust for polling + const usePolling = this.options?.watcher?.recursive?.usePolling; + if (usePolling === true) { + request.pollingInterval = this.options?.watcher?.recursive?.pollingInterval ?? 5000; + } else if (Array.isArray(usePolling)) { + if (usePolling.includes(request.path)) { + request.pollingInterval = this.options?.watcher?.recursive?.pollingInterval ?? 5000; + } + } + + // Adjust for next version + if (this.options?.watcher?.recursive?.useNext) { + request.useNext = true; + } + } + + return request; + } + private refreshUniversalWatchers(): void { // Buffer requests for universal watching to decide on right watcher @@ -121,24 +143,6 @@ export abstract class AbstractDiskFileSystemProvider extends Disposable implemen })); } - // Adjust for polling - const usePolling = this.options?.watcher?.recursive?.usePolling; - if (usePolling === true) { - for (const request of this.universalWatchRequests) { - if (isRecursiveWatchRequest(request)) { - request.pollingInterval = this.options?.watcher?.recursive?.pollingInterval ?? 5000; - } - } - } else if (Array.isArray(usePolling)) { - for (const request of this.universalWatchRequests) { - if (isRecursiveWatchRequest(request)) { - if (usePolling.includes(request.path)) { - request.pollingInterval = this.options?.watcher?.recursive?.pollingInterval ?? 5000; - } - } - } - } - // Ask to watch the provided paths return this.universalWatcher.watch(this.universalWatchRequests); } diff --git a/src/vs/platform/files/common/watcher.ts b/src/vs/platform/files/common/watcher.ts index ff0fd505d18d3..343ac19483fcb 100644 --- a/src/vs/platform/files/common/watcher.ts +++ b/src/vs/platform/files/common/watcher.ts @@ -80,6 +80,11 @@ export interface IRecursiveWatchRequest extends IWatchRequest { * be used in any other case. */ pollingInterval?: number; + + /** + * TODO@bpasero Temporary flag to test the new watcher implementation + */ + useNext?: boolean; } export function isRecursiveWatchRequest(request: IWatchRequest): request is IRecursiveWatchRequest { @@ -169,6 +174,11 @@ export interface IRecursiveWatcherOptions { * be used in any other case. */ readonly pollingInterval?: number; + + /** + * TODO@bpasero Temporary flag to test the new watcher implementation + */ + readonly useNext?: boolean; } export interface INonRecursiveWatcher extends IWatcher { diff --git a/src/vs/platform/files/electron-main/diskFileSystemProviderServer.ts b/src/vs/platform/files/electron-main/diskFileSystemProviderServer.ts index 649a620f7a942..8ae6363af1bad 100644 --- a/src/vs/platform/files/electron-main/diskFileSystemProviderServer.ts +++ b/src/vs/platform/files/electron-main/diskFileSystemProviderServer.ts @@ -17,13 +17,15 @@ import { AbstractDiskFileSystemProviderChannel, AbstractSessionFileWatcher, ISes import { DefaultURITransformer, IURITransformer } from '../../../base/common/uriIpc.js'; import { IEnvironmentService } from '../../environment/common/environment.js'; import { toErrorMessage } from '../../../base/common/errorMessage.js'; +import { IConfigurationService } from '../../configuration/common/configuration.js'; export class DiskFileSystemProviderChannel extends AbstractDiskFileSystemProviderChannel { constructor( provider: DiskFileSystemProvider, logService: ILogService, - private readonly environmentService: IEnvironmentService + private readonly environmentService: IEnvironmentService, + private readonly configurationService: IConfigurationService ) { super(provider, logService); } @@ -57,7 +59,7 @@ export class DiskFileSystemProviderChannel extends AbstractDiskFileSystemProvide //#region File Watching protected createSessionFileWatcher(uriTransformer: IURITransformer, emitter: Emitter): ISessionFileWatcher { - return new SessionFileWatcher(uriTransformer, emitter, this.logService, this.environmentService); + return new SessionFileWatcher(uriTransformer, emitter, this.logService, this.environmentService, this.configurationService); } //#endregion diff --git a/src/vs/platform/files/node/diskFileSystemProviderServer.ts b/src/vs/platform/files/node/diskFileSystemProviderServer.ts index 05b8349b9c715..31efeb9e2fe80 100644 --- a/src/vs/platform/files/node/diskFileSystemProviderServer.ts +++ b/src/vs/platform/files/node/diskFileSystemProviderServer.ts @@ -16,6 +16,7 @@ import { IStat, IFileReadStreamOptions, IFileWriteOptions, IFileOpenOptions, IFi import { CancellationTokenSource } from '../../../base/common/cancellation.js'; import { IRecursiveWatcherOptions } from '../common/watcher.js'; import { IEnvironmentService } from '../../environment/common/environment.js'; +import { IConfigurationService } from '../../configuration/common/configuration.js'; export interface ISessionFileWatcher extends IDisposable { watch(req: number, resource: URI, opts: IWatchOptions): IDisposable; @@ -278,7 +279,8 @@ export abstract class AbstractSessionFileWatcher extends Disposable implements I private readonly uriTransformer: IURITransformer, sessionEmitter: Emitter, private readonly logService: ILogService, - private readonly environmentService: IEnvironmentService + private readonly environmentService: IEnvironmentService, + private readonly configurationService: IConfigurationService ) { super(); @@ -303,7 +305,11 @@ export abstract class AbstractSessionFileWatcher extends Disposable implements I } protected getRecursiveWatcherOptions(environmentService: IEnvironmentService): IRecursiveWatcherOptions | undefined { - return undefined; // subclasses can override + if (this.configurationService.getValue('files.experimentalWatcherNext') === true) { + return { useNext: true, usePolling: false }; + } + + return undefined; } protected getExtraExcludes(environmentService: IEnvironmentService): string[] | undefined { diff --git a/src/vs/platform/files/node/watcher/parcel/parcelWatcher.ts b/src/vs/platform/files/node/watcher/parcel/parcelWatcher.ts index ee38b02a7659c..8ed3967c46762 100644 --- a/src/vs/platform/files/node/watcher/parcel/parcelWatcher.ts +++ b/src/vs/platform/files/node/watcher/parcel/parcelWatcher.ts @@ -25,9 +25,6 @@ import { FileChangeType, IFileChange } from '../../../common/files.js'; import { coalesceEvents, IRecursiveWatchRequest, parseWatcherPatterns, IRecursiveWatcherWithSubscribe, isFiltered, IWatcherErrorEvent } from '../../../common/watcher.js'; import { Disposable, DisposableStore, IDisposable, toDisposable } from '../../../../../base/common/lifecycle.js'; -const useParcelWatcher2 = process.env.VSCODE_USE_WATCHER2 === 'true'; -const parcelWatcherLib = useParcelWatcher2 ? parcelWatcher2 : parcelWatcher; - export class ParcelWatcherInstance extends Disposable { private readonly _onDidStop = this._register(new Emitter<{ joinRestart?: Promise }>()); @@ -293,7 +290,7 @@ export class ParcelWatcher extends BaseWatcher implements IRecursiveWatcherWithS // Path checks for symbolic links / wrong casing const { realPath, realPathDiffers, realPathLength } = this.normalizePath(request); - this.trace(`Started watching: '${realPath}' with polling interval '${pollingInterval}'`); + this.trace(`Started watching: '${realPath}' with polling interval '${pollingInterval}' and version '${request.useNext ? 'next' : 'stable'}'`); let counter = 0; @@ -305,6 +302,7 @@ export class ParcelWatcher extends BaseWatcher implements IRecursiveWatcherWithS } // We already ran before, check for events since + const parcelWatcherLib = request.useNext ? parcelWatcher2 : parcelWatcher; if (counter > 1) { const parcelEvents = await parcelWatcherLib.getEventsSince(realPath, snapshotFile, { ignore: this.addPredefinedExcludes(request.excludes), backend: ParcelWatcher.PARCEL_WATCHER_BACKEND }); @@ -362,6 +360,7 @@ export class ParcelWatcher extends BaseWatcher implements IRecursiveWatcherWithS const { realPath, realPathDiffers, realPathLength } = this.normalizePath(request); try { + const parcelWatcherLib = request.useNext ? parcelWatcher2 : parcelWatcher; const parcelWatcherInstance = await parcelWatcherLib.subscribe(realPath, (error, parcelEvents) => { if (watcher.token.isCancellationRequested) { return; // return early when disposed @@ -382,7 +381,7 @@ export class ParcelWatcher extends BaseWatcher implements IRecursiveWatcherWithS ignore: this.addPredefinedExcludes(watcher.request.excludes) }); - this.trace(`Started watching: '${realPath}' with backend '${ParcelWatcher.PARCEL_WATCHER_BACKEND}'`); + this.trace(`Started watching: '${realPath}' with backend '${ParcelWatcher.PARCEL_WATCHER_BACKEND}' and version '${request.useNext ? 'next' : 'stable'}'`); instance.complete(parcelWatcherInstance); } catch (error) { @@ -862,7 +861,7 @@ export class ParcelWatcher extends BaseWatcher implements IRecursiveWatcherWithS } private toMessage(message: string, request?: IRecursiveWatchRequest): string { - return request ? `[File Watcher (${useParcelWatcher2 ? 'parcel-next' : 'parcel-classic'})] ${message} (path: ${request.path})` : `[File Watcher (${useParcelWatcher2 ? 'parcel-next' : 'parcel-classic'})] ${message}`; + return request ? `[File Watcher (${request.useNext ? 'parcel-next' : 'parcel-classic'})] ${message} (path: ${request.path})` : `[File Watcher ('parcel')] ${message}`; } protected get recursiveWatcher() { return this; } diff --git a/src/vs/platform/files/node/watcher/watcher.ts b/src/vs/platform/files/node/watcher/watcher.ts index 1652082cc1c07..261f7830cd900 100644 --- a/src/vs/platform/files/node/watcher/watcher.ts +++ b/src/vs/platform/files/node/watcher/watcher.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { Disposable } from '../../../../base/common/lifecycle.js'; -import { ILogMessage, IUniversalWatcher, IUniversalWatchRequest } from '../../common/watcher.js'; +import { ILogMessage, isRecursiveWatchRequest, IUniversalWatcher, IUniversalWatchRequest } from '../../common/watcher.js'; import { Emitter, Event } from '../../../../base/common/event.js'; import { ParcelWatcher } from './parcel/parcelWatcher.js'; import { NodeJSWatcher } from './nodejs/nodejsWatcher.js'; @@ -33,13 +33,13 @@ export class UniversalWatcher extends Disposable implements IUniversalWatcher { let error: Error | undefined; try { - await this.recursiveWatcher.watch(requests.filter(request => request.recursive)); + await this.recursiveWatcher.watch(requests.filter(request => isRecursiveWatchRequest(request))); } catch (e) { error = e; } try { - await this.nonRecursiveWatcher.watch(requests.filter(request => !request.recursive)); + await this.nonRecursiveWatcher.watch(requests.filter(request => !isRecursiveWatchRequest(request))); } catch (e) { if (!error) { error = e; diff --git a/src/vs/platform/files/node/watcher/watcherStats.ts b/src/vs/platform/files/node/watcher/watcherStats.ts index af911739c4737..2242d0d9faf7f 100644 --- a/src/vs/platform/files/node/watcher/watcherStats.ts +++ b/src/vs/platform/files/node/watcher/watcherStats.ts @@ -3,12 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IUniversalWatchRequest, requestFilterToString } from '../../common/watcher.js'; +import { INonRecursiveWatchRequest, IRecursiveWatchRequest, isRecursiveWatchRequest, IUniversalWatchRequest, requestFilterToString } from '../../common/watcher.js'; import { INodeJSWatcherInstance, NodeJSWatcher } from './nodejs/nodejsWatcher.js'; import { ParcelWatcher, ParcelWatcherInstance } from './parcel/parcelWatcher.js'; -const useParcelWatcher2 = process.env.VSCODE_USE_WATCHER2 === 'true'; - export function computeStats( requests: IUniversalWatchRequest[], recursiveWatcher: ParcelWatcher, @@ -16,7 +14,7 @@ export function computeStats( ): string { const lines: string[] = []; - const allRecursiveRequests = sortByPathPrefix(requests.filter(request => request.recursive)); + const allRecursiveRequests = sortByPathPrefix(requests.filter(request => isRecursiveWatchRequest(request))); const nonSuspendedRecursiveRequests = allRecursiveRequests.filter(request => recursiveWatcher.isSuspended(request) === false); const suspendedPollingRecursiveRequests = allRecursiveRequests.filter(request => recursiveWatcher.isSuspended(request) === 'polling'); const suspendedNonPollingRecursiveRequests = allRecursiveRequests.filter(request => recursiveWatcher.isSuspended(request) === true); @@ -24,7 +22,7 @@ export function computeStats( const recursiveRequestsStatus = computeRequestStatus(allRecursiveRequests, recursiveWatcher); const recursiveWatcherStatus = computeRecursiveWatchStatus(recursiveWatcher); - const allNonRecursiveRequests = sortByPathPrefix(requests.filter(request => !request.recursive)); + const allNonRecursiveRequests = sortByPathPrefix(requests.filter(request => !isRecursiveWatchRequest(request))); const nonSuspendedNonRecursiveRequests = allNonRecursiveRequests.filter(request => nonRecursiveWatcher.isSuspended(request) === false); const suspendedPollingNonRecursiveRequests = allNonRecursiveRequests.filter(request => nonRecursiveWatcher.isSuspended(request) === 'polling'); const suspendedNonPollingNonRecursiveRequests = allNonRecursiveRequests.filter(request => nonRecursiveWatcher.isSuspended(request) === true); @@ -61,7 +59,7 @@ export function computeStats( fillNonRecursiveWatcherStats(nonRecursiveWatcheLines, nonRecursiveWatcher); lines.push(...alignTextColumns(nonRecursiveWatcheLines)); - return useParcelWatcher2 ? `\n\n[File Watcher NEXT] request stats:\n\n${lines.join('\n')}\n\n` : `\n\n[File Watcher CLASSIC] request stats:\n\n${lines.join('\n')}\n\n`; + return allRecursiveRequests.some(r => r.useNext) ? `\n\n[File Watcher NEXT] request stats:\n\n${lines.join('\n')}\n\n` : `\n\n[File Watcher CLASSIC] request stats:\n\n${lines.join('\n')}\n\n`; } function alignTextColumns(lines: string[]) { @@ -142,6 +140,8 @@ function computeNonRecursiveWatchStatus(nonRecursiveWatcher: NodeJSWatcher): { a return { active, failed, reusing }; } +function sortByPathPrefix(requests: IRecursiveWatchRequest[]): IRecursiveWatchRequest[]; +function sortByPathPrefix(requests: INonRecursiveWatchRequest[]): INonRecursiveWatchRequest[]; function sortByPathPrefix(requests: IUniversalWatchRequest[]): IUniversalWatchRequest[]; function sortByPathPrefix(requests: INodeJSWatcherInstance[]): INodeJSWatcherInstance[]; function sortByPathPrefix(requests: ParcelWatcherInstance[]): ParcelWatcherInstance[]; diff --git a/src/vs/platform/utilityProcess/electron-main/utilityProcessWorkerMainService.ts b/src/vs/platform/utilityProcess/electron-main/utilityProcessWorkerMainService.ts index 2a622905d4b60..9ab01b9be15db 100644 --- a/src/vs/platform/utilityProcess/electron-main/utilityProcessWorkerMainService.ts +++ b/src/vs/platform/utilityProcess/electron-main/utilityProcessWorkerMainService.ts @@ -8,13 +8,12 @@ import { createDecorator } from '../../instantiation/common/instantiation.js'; import { ILogService } from '../../log/common/log.js'; import { IUtilityProcessWorkerCreateConfiguration, IOnDidTerminateUtilityrocessWorkerProcess, IUtilityProcessWorkerConfiguration, IUtilityProcessWorkerProcessExit, IUtilityProcessWorkerService } from '../common/utilityProcessWorkerService.js'; import { IWindowsMainService } from '../../windows/electron-main/windows.js'; -import { IWindowUtilityProcessConfiguration, WindowUtilityProcess } from './utilityProcess.js'; +import { WindowUtilityProcess } from './utilityProcess.js'; import { ITelemetryService } from '../../telemetry/common/telemetry.js'; import { hash } from '../../../base/common/hash.js'; import { Event, Emitter } from '../../../base/common/event.js'; import { DeferredPromise } from '../../../base/common/async.js'; import { ILifecycleMainService } from '../../lifecycle/electron-main/lifecycleMainService.js'; -import { IConfigurationService } from '../../configuration/common/configuration.js'; export const IUtilityProcessWorkerMainService = createDecorator('utilityProcessWorker'); @@ -33,8 +32,7 @@ export class UtilityProcessWorkerMainService extends Disposable implements IUtil @ILogService private readonly logService: ILogService, @IWindowsMainService private readonly windowsMainService: IWindowsMainService, @ITelemetryService private readonly telemetryService: ITelemetryService, - @ILifecycleMainService private readonly lifecycleMainService: ILifecycleMainService, - @IConfigurationService private readonly configurationService: IConfigurationService + @ILifecycleMainService private readonly lifecycleMainService: ILifecycleMainService ) { super(); } @@ -52,7 +50,7 @@ export class UtilityProcessWorkerMainService extends Disposable implements IUtil } // Create new worker - const worker = new UtilityProcessWorker(this.logService, this.windowsMainService, this.telemetryService, this.lifecycleMainService, this.configurationService, configuration); + const worker = new UtilityProcessWorker(this.logService, this.windowsMainService, this.telemetryService, this.lifecycleMainService, configuration); if (!worker.spawn()) { return { reason: { code: 1, signal: 'EINVALID' } }; } @@ -108,7 +106,6 @@ class UtilityProcessWorker extends Disposable { @IWindowsMainService private readonly windowsMainService: IWindowsMainService, @ITelemetryService private readonly telemetryService: ITelemetryService, @ILifecycleMainService private readonly lifecycleMainService: ILifecycleMainService, - @IConfigurationService private readonly configurationService: IConfigurationService, private readonly configuration: IUtilityProcessWorkerCreateConfiguration ) { super(); @@ -125,7 +122,7 @@ class UtilityProcessWorker extends Disposable { const window = this.windowsMainService.getWindowById(this.configuration.reply.windowId); const windowPid = window?.win?.webContents.getOSProcessId(); - let configuration: IWindowUtilityProcessConfiguration = { + return this.utilityProcess.start({ type: this.configuration.process.type, entryPoint: this.configuration.process.moduleId, parentLifecycleBound: windowPid, @@ -134,18 +131,7 @@ class UtilityProcessWorker extends Disposable { responseWindowId: this.configuration.reply.windowId, responseChannel: this.configuration.reply.channel, responseNonce: this.configuration.reply.nonce - }; - - if (this.configuration.process.type === 'fileWatcher' && this.configurationService.getValue('files.experimentalWatcherNext') === true) { - configuration = { - ...configuration, - env: { - VSCODE_USE_WATCHER2: 'true' - } - }; - } - - return this.utilityProcess.start(configuration); + }); } kill() { diff --git a/src/vs/server/node/remoteFileSystemProviderServer.ts b/src/vs/server/node/remoteFileSystemProviderServer.ts index c963f1cdd28ef..00c9b24f584fa 100644 --- a/src/vs/server/node/remoteFileSystemProviderServer.ts +++ b/src/vs/server/node/remoteFileSystemProviderServer.ts @@ -15,6 +15,7 @@ import { posix, delimiter } from '../../base/common/path.js'; import { IServerEnvironmentService } from './serverEnvironmentService.js'; import { AbstractDiskFileSystemProviderChannel, AbstractSessionFileWatcher, ISessionFileWatcher } from '../../platform/files/node/diskFileSystemProviderServer.js'; import { IRecursiveWatcherOptions } from '../../platform/files/common/watcher.js'; +import { IConfigurationService } from '../../platform/configuration/common/configuration.js'; export class RemoteAgentFileSystemProviderChannel extends AbstractDiskFileSystemProviderChannel { @@ -22,7 +23,8 @@ export class RemoteAgentFileSystemProviderChannel extends AbstractDiskFileSystem constructor( logService: ILogService, - private readonly environmentService: IServerEnvironmentService + private readonly environmentService: IServerEnvironmentService, + private readonly configurationService: IConfigurationService ) { super(new DiskFileSystemProvider(logService), logService); @@ -52,7 +54,7 @@ export class RemoteAgentFileSystemProviderChannel extends AbstractDiskFileSystem //#region File Watching protected createSessionFileWatcher(uriTransformer: IURITransformer, emitter: Emitter): ISessionFileWatcher { - return new SessionFileWatcher(uriTransformer, emitter, this.logService, this.environmentService); + return new SessionFileWatcher(uriTransformer, emitter, this.logService, this.environmentService, this.configurationService); } //#endregion @@ -64,23 +66,26 @@ class SessionFileWatcher extends AbstractSessionFileWatcher { uriTransformer: IURITransformer, sessionEmitter: Emitter, logService: ILogService, - environmentService: IServerEnvironmentService + environmentService: IServerEnvironmentService, + configurationService: IConfigurationService ) { - super(uriTransformer, sessionEmitter, logService, environmentService); + super(uriTransformer, sessionEmitter, logService, environmentService, configurationService); } protected override getRecursiveWatcherOptions(environmentService: IServerEnvironmentService): IRecursiveWatcherOptions | undefined { + const options = super.getRecursiveWatcherOptions(environmentService); + const fileWatcherPolling = environmentService.args['file-watcher-polling']; if (fileWatcherPolling) { const segments = fileWatcherPolling.split(delimiter); const pollingInterval = Number(segments[0]); if (pollingInterval > 0) { const usePolling = segments.length > 1 ? segments.slice(1) : true; - return { usePolling, pollingInterval }; + return { ...options, usePolling, pollingInterval }; } } - return undefined; + return options; } protected override getExtraExcludes(environmentService: IServerEnvironmentService): string[] | undefined { diff --git a/src/vs/server/node/serverServices.ts b/src/vs/server/node/serverServices.ts index 70ebf61f8577e..cd1091150dbbe 100644 --- a/src/vs/server/node/serverServices.ts +++ b/src/vs/server/node/serverServices.ts @@ -221,7 +221,7 @@ export async function setupServerServices(connectionToken: ServerConnectionToken const remoteExtensionsScanner = new RemoteExtensionsScannerService(instantiationService.createInstance(ExtensionManagementCLI, logService), environmentService, userDataProfilesService, extensionsScannerService, logService, extensionGalleryService, languagePackService); socketServer.registerChannel(RemoteExtensionsScannerChannelName, new RemoteExtensionsScannerChannel(remoteExtensionsScanner, (ctx: RemoteAgentConnectionContext) => getUriTransformer(ctx.remoteAuthority))); - const remoteFileSystemChannel = disposables.add(new RemoteAgentFileSystemProviderChannel(logService, environmentService)); + const remoteFileSystemChannel = disposables.add(new RemoteAgentFileSystemProviderChannel(logService, environmentService, configurationService)); socketServer.registerChannel(REMOTE_FILE_SYSTEM_CHANNEL_NAME, remoteFileSystemChannel); socketServer.registerChannel('request', new RequestChannel(accessor.get(IRequestService))); diff --git a/src/vs/workbench/contrib/files/browser/files.contribution.ts b/src/vs/workbench/contrib/files/browser/files.contribution.ts index 68ad1b72c93cc..e94ba03a7b677 100644 --- a/src/vs/workbench/contrib/files/browser/files.contribution.ts +++ b/src/vs/workbench/contrib/files/browser/files.contribution.ts @@ -312,7 +312,7 @@ configurationRegistry.registerConfiguration({ 'type': 'boolean', 'default': false, 'markdownDescription': nls.localize('experimentalWatcherNext', "Enables a newer, experimental version of the file watcher."), - scope: ConfigurationScope.APPLICATION + scope: ConfigurationScope.MACHINE }, 'files.hotExit': hotExitConfiguration, 'files.defaultLanguage': { diff --git a/src/vs/workbench/electron-sandbox/desktop.main.ts b/src/vs/workbench/electron-sandbox/desktop.main.ts index 24d89f630d0b2..39d87cf6b6731 100644 --- a/src/vs/workbench/electron-sandbox/desktop.main.ts +++ b/src/vs/workbench/electron-sandbox/desktop.main.ts @@ -307,6 +307,10 @@ export class DesktopMain extends Disposable { }) ]); + if (configurationService.getValue('files.experimentalWatcherNext') === true) { + diskFileSystemProvider.setUseNextWatcher(); + } + // Workspace Trust Service const workspaceTrustEnablementService = new WorkspaceTrustEnablementService(configurationService, environmentService); serviceCollection.set(IWorkspaceTrustEnablementService, workspaceTrustEnablementService); diff --git a/src/vs/workbench/services/files/electron-sandbox/diskFileSystemProvider.ts b/src/vs/workbench/services/files/electron-sandbox/diskFileSystemProvider.ts index c037805a6d351..140998992a211 100644 --- a/src/vs/workbench/services/files/electron-sandbox/diskFileSystemProvider.ts +++ b/src/vs/workbench/services/files/electron-sandbox/diskFileSystemProvider.ts @@ -45,6 +45,10 @@ export class DiskFileSystemProvider extends AbstractDiskFileSystemProvider imple this.registerListeners(); } + setUseNextWatcher(): void { + this.options = { watcher: { forceUniversal: true, recursive: { useNext: true, usePolling: false } } }; + } + private registerListeners(): void { // Forward events from the embedded provider