Skip to content

Commit e7f92b2

Browse files
committed
Refactoring
1 parent 3cdbbcf commit e7f92b2

File tree

1 file changed

+61
-56
lines changed

1 file changed

+61
-56
lines changed

src/remote/sshProcess.ts

Lines changed: 61 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -28,58 +28,15 @@ export interface SshProcessMonitorOptions {
2828
networkInfoPath: string;
2929
proxyLogDir?: string;
3030
logger: Logger;
31+
// Poll interval for SSH process and file discovery
3132
pollInterval?: number;
33+
// Poll interval for network info updates
3234
networkPollInterval?: number;
3335
// For port-based SSH process discovery
3436
codeLogDir: string;
3537
remoteSshExtensionId: string;
3638
}
3739

38-
/**
39-
* Finds the Remote SSH extension's log file path.
40-
*/
41-
async function findRemoteSshLogPath(
42-
codeLogDir: string,
43-
extensionId: string,
44-
): Promise<string | undefined> {
45-
const logsParentDir = path.dirname(codeLogDir);
46-
47-
// Try extension-specific folder (for VS Code clones like Cursor, Windsurf)
48-
try {
49-
const extensionLogDir = path.join(logsParentDir, extensionId);
50-
// Node returns these directories sorted already!
51-
const files = await fs.readdir(extensionLogDir);
52-
files.reverse();
53-
54-
const remoteSsh = files.find((file) => file.includes("Remote - SSH"));
55-
if (remoteSsh) {
56-
return path.join(extensionLogDir, remoteSsh);
57-
}
58-
} catch {
59-
// Extension-specific folder doesn't exist, try fallback
60-
}
61-
62-
try {
63-
// Node returns these directories sorted already!
64-
const dirs = await fs.readdir(logsParentDir);
65-
dirs.reverse();
66-
const outputDirs = dirs.filter((d) => d.startsWith("output_logging_"));
67-
68-
if (outputDirs.length > 0) {
69-
const outputPath = path.join(logsParentDir, outputDirs[0]);
70-
const files = await fs.readdir(outputPath);
71-
const remoteSSHLog = files.find((f) => f.includes("Remote - SSH"));
72-
if (remoteSSHLog) {
73-
return path.join(outputPath, remoteSSHLog);
74-
}
75-
}
76-
} catch {
77-
// output_logging folder doesn't exist
78-
}
79-
80-
return undefined;
81-
}
82-
8340
/**
8441
* Monitors the SSH process for a Coder workspace connection and displays
8542
* network status in the VS Code status bar.
@@ -116,6 +73,7 @@ export class SshProcessMonitor implements vscode.Disposable {
11673
...options,
11774
proxyLogDir: options.proxyLogDir,
11875
pollInterval: options.pollInterval ?? 1000,
76+
// Matches the SSH update interval
11977
networkPollInterval: options.networkPollInterval ?? 3000,
12078
};
12179
this.statusBarItem = vscode.window.createStatusBarItem(
@@ -128,7 +86,7 @@ export class SshProcessMonitor implements vscode.Disposable {
12886
* Creates and starts an SSH process monitor.
12987
* Begins searching for the SSH process in the background.
13088
*/
131-
static start(options: SshProcessMonitorOptions): SshProcessMonitor {
89+
public static start(options: SshProcessMonitorOptions): SshProcessMonitor {
13290
const monitor = new SshProcessMonitor(options);
13391
monitor.searchForProcess().catch((err) => {
13492
options.logger.error("Error in SSH process monitor", err);
@@ -187,16 +145,14 @@ export class SshProcessMonitor implements vscode.Disposable {
187145
while (!this.disposed) {
188146
attempt++;
189147

190-
if (attempt % 10 === 0) {
148+
if (attempt === 1 || attempt % 10 === 0) {
191149
logger.debug(
192150
`SSH process search attempt ${attempt} for host: ${sshHost}`,
193151
);
194152
}
195153

196-
// Try port-based discovery first (unique per VS Code window)
197154
const pidByPort = await this.findSshProcessByPort();
198155
if (pidByPort !== undefined) {
199-
logger.info(`Found SSH process by port (PID: ${pidByPort})`);
200156
this.setCurrentPid(pidByPort);
201157
this.startMonitoring();
202158
return;
@@ -250,16 +206,16 @@ export class SshProcessMonitor implements vscode.Disposable {
250206
const previousPid = this.currentPid;
251207
this.currentPid = pid;
252208

253-
if (previousPid !== undefined && previousPid !== pid) {
209+
if (previousPid === undefined) {
210+
this.options.logger.info(`SSH connection established (PID: ${pid})`);
211+
this._onPidChange.fire(pid);
212+
} else if (previousPid !== pid) {
254213
this.options.logger.info(
255214
`SSH process changed from ${previousPid} to ${pid}`,
256215
);
257216
this.logFilePath = undefined;
258217
this._onLogFilePathChange.fire(undefined);
259218
this._onPidChange.fire(pid);
260-
} else if (previousPid === undefined) {
261-
this.options.logger.info(`SSH connection established (PID: ${pid})`);
262-
this._onPidChange.fire(pid);
263219
}
264220
}
265221

@@ -349,7 +305,8 @@ export class SshProcessMonitor implements vscode.Disposable {
349305

350306
const content = await fs.readFile(networkInfoFile, "utf8");
351307
const network = JSON.parse(content) as NetworkInfo;
352-
this.updateStatusBar(network);
308+
const isStale = ageMs > this.options.networkPollInterval * 2;
309+
this.updateStatusBar(network, isStale);
353310
} catch (error) {
354311
logger.debug(
355312
`Failed to read network info: ${(error as Error).message}`,
@@ -363,7 +320,7 @@ export class SshProcessMonitor implements vscode.Disposable {
363320
/**
364321
* Updates the status bar with network information.
365322
*/
366-
private updateStatusBar(network: NetworkInfo): void {
323+
private updateStatusBar(network: NetworkInfo, isStale: boolean): void {
367324
let statusText = "$(globe) ";
368325

369326
// Coder Connect doesn't populate any other stats
@@ -409,8 +366,56 @@ export class SshProcessMonitor implements vscode.Disposable {
409366
}
410367

411368
this.statusBarItem.tooltip = tooltip;
412-
statusText += "(" + network.latency.toFixed(2) + "ms)";
369+
const latencyText = isStale
370+
? `(~${network.latency.toFixed(2)}ms)`
371+
: `(${network.latency.toFixed(2)}ms)`;
372+
statusText += latencyText;
413373
this.statusBarItem.text = statusText;
414374
this.statusBarItem.show();
415375
}
416376
}
377+
378+
/**
379+
* Finds the Remote SSH extension's log file path.
380+
*/
381+
async function findRemoteSshLogPath(
382+
codeLogDir: string,
383+
extensionId: string,
384+
): Promise<string | undefined> {
385+
const logsParentDir = path.dirname(codeLogDir);
386+
387+
// Try extension-specific folder (for VS Code clones like Cursor, Windsurf)
388+
try {
389+
const extensionLogDir = path.join(logsParentDir, extensionId);
390+
// Node returns these directories sorted already!
391+
const files = await fs.readdir(extensionLogDir);
392+
files.reverse();
393+
394+
const remoteSsh = files.find((file) => file.includes("Remote - SSH"));
395+
if (remoteSsh) {
396+
return path.join(extensionLogDir, remoteSsh);
397+
}
398+
} catch {
399+
// Extension-specific folder doesn't exist, try fallback
400+
}
401+
402+
try {
403+
// Node returns these directories sorted already!
404+
const dirs = await fs.readdir(logsParentDir);
405+
dirs.reverse();
406+
const outputDirs = dirs.filter((d) => d.startsWith("output_logging_"));
407+
408+
if (outputDirs.length > 0) {
409+
const outputPath = path.join(logsParentDir, outputDirs[0]);
410+
const files = await fs.readdir(outputPath);
411+
const remoteSSHLog = files.find((f) => f.includes("Remote - SSH"));
412+
if (remoteSSHLog) {
413+
return path.join(outputPath, remoteSSHLog);
414+
}
415+
}
416+
} catch {
417+
// output_logging folder doesn't exist
418+
}
419+
420+
return undefined;
421+
}

0 commit comments

Comments
 (0)