@@ -20,15 +20,6 @@ export interface NetworkInfo {
2020 using_coder_connect : boolean ;
2121}
2222
23- /**
24- * Process information from find-process.
25- */
26- interface ProcessInfo {
27- pid : number ;
28- name : string ;
29- cmd : string ;
30- }
31-
3223/**
3324 * Options for creating an SshProcessMonitor.
3425 */
@@ -44,27 +35,6 @@ export interface SshProcessMonitorOptions {
4435 remoteSshExtensionId : string ;
4536}
4637
47- /**
48- * Checks if a process is an actual SSH process (not a shell wrapper).
49- * Filters out processes like "sh -c ... | ssh ..." where ssh appears mid-command.
50- */
51- function isActualSshProcess ( p : ProcessInfo ) : boolean {
52- // Process name is exactly "ssh" or "ssh.exe"
53- if ( p . name === "ssh" || p . name === "ssh.exe" ) {
54- return true ;
55- }
56- // Command starts with ssh binary (not piped through shell)
57- if ( / ^ ( s s h | s s h \. e x e ) \s / i. test ( p . cmd ) ) {
58- return true ;
59- }
60- // Command starts with full path to ssh (Unix or Windows)
61- // e.g., "/usr/bin/ssh " or "C:\Program Files\OpenSSH\ssh.exe "
62- if ( / ^ [ \w / \\ : . - ] + ( [ / \\ ] ) s s h ( \. e x e ) ? \s / i. test ( p . cmd ) ) {
63- return true ;
64- }
65- return false ;
66- }
67-
6838/**
6939 * Finds the Remote SSH extension's log file path.
7040 */
@@ -139,6 +109,7 @@ export class SshProcessMonitor implements vscode.Disposable {
139109 private currentPid : number | undefined ;
140110 private logFilePath : string | undefined ;
141111 private pendingTimeout : NodeJS . Timeout | undefined ;
112+ private lastStaleSearchTime = 0 ;
142113
143114 private constructor ( options : SshProcessMonitorOptions ) {
144115 this . options = {
@@ -216,7 +187,7 @@ export class SshProcessMonitor implements vscode.Disposable {
216187 while ( ! this . disposed ) {
217188 attempt ++ ;
218189
219- if ( attempt % 5 === 0 ) {
190+ if ( attempt % 10 === 0 ) {
220191 logger . debug (
221192 `SSH process search attempt ${ attempt } for host: ${ sshHost } ` ,
222193 ) ;
@@ -231,15 +202,6 @@ export class SshProcessMonitor implements vscode.Disposable {
231202 return ;
232203 }
233204
234- // Fall back to hostname-based search
235- // const pidByHost = await this.findSshProcessByHost();
236- // if (pidByHost !== undefined) {
237- // logger.info(`Found SSH process by hostname (PID: ${pidByHost})`);
238- // this.setCurrentPid(pidByHost);
239- // this.startMonitoring();
240- // return;
241- // }
242-
243205 await this . delay ( pollInterval ) ;
244206 }
245207 }
@@ -262,6 +224,7 @@ export class SshProcessMonitor implements vscode.Disposable {
262224
263225 const logContent = await fs . readFile ( logPath , "utf8" ) ;
264226 this . options . logger . debug ( `Read Remote SSH log file: ${ logPath } ` ) ;
227+
265228 const port = findPort ( logContent ) ;
266229 if ( ! port ) {
267230 return undefined ;
@@ -280,45 +243,6 @@ export class SshProcessMonitor implements vscode.Disposable {
280243 }
281244 }
282245
283- /**
284- * Attempts to find an SSH process by hostname.
285- * Less accurate than port-based as multiple windows may connect to same host.
286- * Returns the PID if found, undefined otherwise.
287- */
288- private async findSshProcessByHost ( ) : Promise < number | undefined > {
289- const { sshHost, logger } = this . options ;
290-
291- try {
292- // Find all processes with "ssh" in name
293- const processes = await find ( "name" , "ssh" ) ;
294- const matches = processes . filter (
295- ( p ) => p . cmd . includes ( sshHost ) && isActualSshProcess ( p ) ,
296- ) ;
297-
298- if ( matches . length === 0 ) {
299- return undefined ;
300- }
301-
302- const preferred = matches . find (
303- ( p ) => p . name === "ssh" || p . name === "ssh.exe" ,
304- ) ;
305- if ( preferred ) {
306- return preferred . pid ;
307- }
308-
309- if ( matches . length > 1 ) {
310- logger . warn (
311- `Found ${ matches . length } SSH processes for host, using first` ,
312- ) ;
313- }
314-
315- return matches [ 0 ] . pid ;
316- } catch ( error ) {
317- logger . debug ( `Error searching for SSH process: ${ error } ` ) ;
318- return undefined ;
319- }
320- }
321-
322246 /**
323247 * Updates the current PID and fires change events.
324248 */
@@ -406,15 +330,20 @@ export class SshProcessMonitor implements vscode.Disposable {
406330 const ageMs = Date . now ( ) - stats . mtime . getTime ( ) ;
407331
408332 if ( ageMs > staleThreshold ) {
409- logger . info (
333+ // Prevent tight loop: if we just searched due to stale, wait before searching again
334+ const timeSinceLastSearch = Date . now ( ) - this . lastStaleSearchTime ;
335+ if ( timeSinceLastSearch < staleThreshold ) {
336+ await this . delay ( staleThreshold - timeSinceLastSearch ) ;
337+ continue ;
338+ }
339+
340+ logger . debug (
410341 `Network info stale (${ Math . round ( ageMs / 1000 ) } s old), searching for new SSH process` ,
411342 ) ;
412- this . currentPid = undefined ;
413- this . statusBarItem . hide ( ) ;
414- this . _onPidChange . fire ( undefined ) ;
415- this . searchForProcess ( ) . catch ( ( err ) => {
416- logger . error ( "Error restarting SSH process search" , err ) ;
417- } ) ;
343+
344+ // searchForProcess will update PID if a different process is found
345+ this . lastStaleSearchTime = Date . now ( ) ;
346+ await this . searchForProcess ( ) ;
418347 return ;
419348 }
420349
0 commit comments