Change:
Type: <bBug</bvscode with wsl: or similar tool to monitor CPU usage when vscode is idle or minimized to the taskbar. Expected: CPU usage for vscode's remote server should stay around 0% at idle conditions. Actual: CPU usage stays between 2-10 % VS Code version: Code 1.91.1 (, 2024-07-09T22:06:49.809Z) OS version: WindowsNT x64 10.0. Modes: Remote OS version: Linux x64 6.6.36.3-microsoft-standard-WSL2 <details<summarySystem Info</summary </details<details<summaryExtensions (10)</summaryExtensionVersion ------ remote-wsl0.88.2 material-icon-theme5.6.0 vim1.27.3 markdown-checkbox0.4.0 gitlens15.2.0 prettier-vscode10.4.0 hexeditor1.10.0 advanced-new-file1.2.2 vscode-fileutils3.10.3 even-better-toml0.19.2 </details<!-- generated by issue reporter --
I had earlier opened the issue at where I provided more in-depth issue description. I'm just going to put the same description here. I recently noticed high CPU usage and faster battery drain (intel cpu) when working with any project under WSL. To find out what's taking so much cpu time (even when I'm doing nothing, apart from staring at the screen), I used to list processes in the order of cpu usage: ! Looked like vscode's remote server running inside wsl is taking CPU. So, I went a little further to profile the running instance of the remote server and I found: ! ! from is being called at a regular interval with a small delay (~1000ms). : ! I was able to trace back to : ! And I finally found where it is being called repeatedly: ! Now, why is it a bug? Because I've disabled all related settings in my config, yet the tunnel monitoring service is running in the background. I expect the service to not be running when or related configs are disabled. The service is currently always running.
Wow, great job, thanks for tracking down the problem!
I'm having trouble understanding this: Is WSL going to end up being a ? I don't think we actually want to show the ports view in WSL even if the Tunnels extension isn't installed.
I agree. For non-managed remote authorities created just via the in the workbench, how did we determine whether or not to show the ports view? We should apply the same logic here...
The ports view is controlled by a context key getting set. It gets set in two ways: an extension that wants the ports view. This is what dev containers does. a tunnel factory getting . Since the tunnel factory is always now, we're always enabling it. I should be able to add a check if the tunnel factory is coming from an extension and only do 2 if that's the case.
Looks like we also show the ports view when there's an extension with an actiation event: Is this perhaps no longer needed with the work you did for tunnels I don't remember exactly why I it.
I've moved the check to happen when there's been a port forwarded.
Looks like this was actually a feature: You can set to disable this. I'm also going to try to improve the description of and .
<!-- AUTHORVERIFICATIONREQUEST --This bug has been fixed in the latest release of ! you can help us out by commenting if things are now working as expected. If things still don't seem right, please ensure you're on version of Insiders (today's or later - you can use in the command palette to check), and leave a comment letting us know what isn't working as expected. Happy Coding!
To verify: the descriptions of and . Verify that you can understand what the settings do and how they're related. (These settings may be a bit confusing. We should consider deprecating and only have ) . to or if it isn't already. the WSL extension, connect to a WSL remote. the log level to Trace for the Remote Extension Host. the output for the Remote Extension Host. Verify that you see a steady stream of log lines that say "candidate" coming in. This means that port discovery is on. to and to . Reload. sure that the log level of the Remote Extension Host is still set to Trace the output for the Remote Extension Host. Verify that you DO NOT see a steady stream of log lines that say "candidate" coming in.
In the WSL workspace, I don't see any log lines that say "candidate" even after starting a Python HTTP server.
I can't repro this. Do you have an old version of WSL installed?
I verified that on my machine the work.
I haven't checked with Insider, but in stable I can confirm 'candidate' logs are not visible after Step 6 of the verification steps. Thanks. I also want to point out that it's not clear from the description that there's a process monitoring service running in the background, and that it can be disabled using . Should the default option be instead of ?
Thanks for trying it out If we set it to , then we might end up not showing any ports in the Ports view. In insiders, I updated the text of the setting: Sets the source from which ports are automatically forwarded when is true. When is false, will be used to find information about ports that have already been forwarded. On Windows and macOS remotes, the process and hybrid options have no effect and output will be used. It still doesn't explicitly say there will be process monitoring, but it should be clearer.

Discussion:
this._register(this.remoteExplorerService.onEnabledPortsFeatures(() => this._proxy.$registerCandidateFinder(this.processFindingEnabled()))); } this._register(this.configurationService.onDidChangeConfiguration(async (e) => { <del> if (e.affectsConfiguration(PORT_AUTO_FORWARD_SETTING) || e.affectsConfiguration(PORT_AUTO_SOURCE_SETTING)) { </del> <ins> if (this.remoteExplorerService.portsFeaturesEnabled && (e.affectsConfiguration(PORT_AUTO_FORWARD_SETTING) || e.affectsConfiguration(PORT_AUTO_SOURCE_SETTING))) { </ins> return this._proxy.$registerCandidateFinder(this.processFindingEnabled()); } })); <del> this._register(this.tunnelService.onAddedTunnelProvider(() => { return this._proxy.$registerCandidateFinder(this.processFindingEnabled()); </del> <ins> this._register(this.tunnelService.onAddedTunnelProvider(async () => { if (this.remoteExplorerService.portsFeaturesEnabled) { return this._proxy.$registerCandidateFinder(this.processFindingEnabled()); } </ins> })); }

$openTunnel(tunnelOptions: TunnelOptions, source: string | undefined): Promise<TunnelDto | undefined>; $closeTunnel(remote: { host: string; port: number }): Promise<void>; $getTunnels(): Promise<TunnelDescription[]>; <del> $setTunnelProvider(features?: TunnelProviderFeatures): Promise<void>; </del> <ins> $setTunnelProvider(features: TunnelProviderFeatures | undefined, enablePortsView: boolean): Promise<void>; </ins> $setRemoteTunnelService(processId: number): Promise<void>; $setCandidateFilter(): Promise<void>; $onFoundNewCandidates(candidates: CandidatePort[]): Promise<void>;

protocol: information.tunnelFeatures.protocol === undefined ? true : information.tunnelFeatures.protocol, } : undefined; <del> this._proxy.$setTunnelProvider(tunnelFeatures); </del> <ins> this._proxy.$setTunnelProvider(tunnelFeatures, true); </ins> return Promise.resolve(toDisposable(() => { this._forwardPortProvider = undefined; <del> this._proxy.$setTunnelProvider(undefined); </del> <ins> this._proxy.$setTunnelProvider(undefined, false); </ins> })); }

protocol: true } : undefined; <del> this._proxy.$setTunnelProvider(tunnelFeatures); </del> <ins> this._proxy.$setTunnelProvider(tunnelFeatures, !!provider.tunnelFactory); </ins> } } else { this._forwardPortProvider = undefined;

}); } await this.storeForwarded(); <ins> this.checkExtensionActivationEvents(); </ins> this.remoteTunnels.set(key, tunnel); this._onForwardPort.fire(this.forwarded.get(key)!); })); this._register(this.tunnelService.onTunnelClosed(address => { return this.onTunnelClosed(address, TunnelCloseReason.Other); })); <del> this.checkExtensionActivationEvents(); </del> } private extensionHasActivationEvent() {