MCPcopy
hub / github.com/coder/mux / SSH2ConnectionPool

Class SSH2ConnectionPool

src/node/runtime/SSH2ConnectionPool.ts:266–664  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

264}
265
266export class SSH2ConnectionPool {
267 private health = new Map<string, ConnectionHealth>();
268 private inflight = new Map<string, Promise<SSH2ConnectionEntry>>();
269 private connections = new Map<string, SSH2ConnectionEntry>();
270
271 async acquireConnection(
272 config: SSHConnectionConfig,
273 options: AcquireConnectionOptions = {}
274 ): Promise<SSH2ConnectionEntry> {
275 const key = makeConnectionKey(config);
276 const timeoutMs = options.timeoutMs ?? DEFAULT_CONNECT_TIMEOUT_MS;
277 const sleep = options.sleep ?? sleepWithAbort;
278 const maxWaitMs = options.maxWaitMs ?? DEFAULT_SSH_MAX_WAIT_MS;
279 const shouldWait = maxWaitMs > 0;
280 const startTime = Date.now();
281
282 while (true) {
283 if (options.abortSignal?.aborted) {
284 throw new Error(SSH2_OPERATION_ABORTED_ERROR);
285 }
286
287 const existing = this.connections.get(key);
288 if (existing) {
289 this.touchConnection(existing, key);
290 this.markHealthy(config);
291 return existing;
292 }
293
294 const health = this.health.get(key);
295 if (health?.backoffUntil && health.backoffUntil > new Date()) {
296 const remainingMs = health.backoffUntil.getTime() - Date.now();
297 const remainingSecs = Math.ceil(remainingMs / 1000);
298
299 if (!shouldWait) {
300 throw new Error(
301 `SSH connection to ${config.host} is in backoff for ${remainingSecs}s. ` +
302 `Last error: ${health.lastError ?? "unknown"}`
303 );
304 }
305
306 const elapsedMs = Date.now() - startTime;
307 const budgetMs = Math.max(0, maxWaitMs - elapsedMs);
308 if (budgetMs <= 0) {
309 throw new Error(
310 `SSH connection to ${config.host} is in backoff and maxWaitMs exceeded. ` +
311 `Last error: ${health.lastError ?? "unknown"}`
312 );
313 }
314
315 const waitMs = Math.min(remainingMs, budgetMs);
316 options.onWait?.(waitMs);
317 await sleep(waitMs, options.abortSignal);
318 continue;
319 }
320
321 let inflight = this.inflight.get(key);
322 if (!inflight) {
323 inflight = this.connect(config, timeoutMs, options.abortSignal);

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected