perf: reuse SSH connections per server, with a retry rule that never repeats work
Every ssh.exec opened its own connection: a TCP handshake, a key exchange and an
authentication round trip per command. A key rotation paid for that eight times,
a deployment six, and refreshing M profile states M times.
Connections are now kept per server. The three risks that made this worth doing
carefully are handled explicitly:
- Staleness. A pooled connection can be dead exactly when it matters. Liveness is
tracked through error, close and end, and a lease that finds a dead entry opens
a new one. The remaining race, where the connection dies between the check and
the command, is caught by the retry rule below.
- Retrying. Only a failure that proves the command never reached the server is
retried, and only once, and only on a connection that was already established
before this call. execClient marks exactly that case, when the channel fails to
open. A command that opened a stream is never repeated, because the server may
already be acting on it - repeating a deployment is not this layer's decision.
Two tests hold that line: widening the rule to any failure fails both.
- Lifetime. Idle connections close after a minute, the pool is reference counted
so a shared connection survives until its last user is done, closeAll runs
during quit, and every pooled client keeps a standing error listener so an
error while idle cannot reach the uncaughtException handler.
A trust-on-first-use connection is never pooled: it was established without
verifying the fingerprint, so it must not serve a later verified call. A change
to host, port, user, auth type, key path or trusted fingerprint invalidates the
pooled connection.
ssh-service coverage rises from 61% to 90% of lines and 97% of functions.
Also in this commit, the smaller items from the same review:
- Diagnostics batched records that queue up while a write is in flight into one
append, and chmod runs once per file instead of once per record. At the debug
level every IPC call writes a line, which is exactly when troubleshooting.
- The set that suppresses duplicate deployment notifications is trimmed instead
of growing for the lifetime of the process.
- The updater kept the same once('error') pattern on its spawned helper that
took the app down through the SSH client.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
beeafdcba7
commit
cb9bdcd713
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"generatedAt": "2026-08-23T12:51:31.496Z",
|
||||
"generatedAt": "2026-08-23T13:06:16.630Z",
|
||||
"thresholds": {
|
||||
"preferredMaximumLines": 750,
|
||||
"justificationRequiredLines": 1000
|
||||
@@ -206,6 +206,23 @@
|
||||
],
|
||||
"hotspotScore": 91
|
||||
},
|
||||
{
|
||||
"file": "main.cjs",
|
||||
"lines": 471,
|
||||
"branches": 39,
|
||||
"functions": 57,
|
||||
"ipcHandlers": 0,
|
||||
"responsibilities": [
|
||||
"inventory",
|
||||
"deployment",
|
||||
"git",
|
||||
"ipc",
|
||||
"renderer",
|
||||
"security",
|
||||
"updates"
|
||||
],
|
||||
"hotspotScore": 89
|
||||
},
|
||||
{
|
||||
"file": "src/renderer/actions/setup-and-settings.js",
|
||||
"lines": 427,
|
||||
@@ -236,21 +253,18 @@
|
||||
"hotspotScore": 87
|
||||
},
|
||||
{
|
||||
"file": "main.cjs",
|
||||
"lines": 463,
|
||||
"branches": 37,
|
||||
"functions": 56,
|
||||
"file": "src/main/ssh-service.cjs",
|
||||
"lines": 467,
|
||||
"branches": 66,
|
||||
"functions": 92,
|
||||
"ipcHandlers": 0,
|
||||
"responsibilities": [
|
||||
"inventory",
|
||||
"deployment",
|
||||
"git",
|
||||
"ipc",
|
||||
"renderer",
|
||||
"security",
|
||||
"updates"
|
||||
],
|
||||
"hotspotScore": 87
|
||||
"hotspotScore": 86
|
||||
},
|
||||
{
|
||||
"file": "src/renderer/actions/deployment-profile.js",
|
||||
@@ -343,6 +357,21 @@
|
||||
],
|
||||
"hotspotScore": 73
|
||||
},
|
||||
{
|
||||
"file": "src/main/diagnostics-service.cjs",
|
||||
"lines": 373,
|
||||
"branches": 39,
|
||||
"functions": 51,
|
||||
"ipcHandlers": 0,
|
||||
"responsibilities": [
|
||||
"deployment",
|
||||
"git",
|
||||
"ipc",
|
||||
"security",
|
||||
"updates"
|
||||
],
|
||||
"hotspotScore": 69
|
||||
},
|
||||
{
|
||||
"file": "src/renderer/events.js",
|
||||
"lines": 181,
|
||||
@@ -372,20 +401,6 @@
|
||||
],
|
||||
"hotspotScore": 63
|
||||
},
|
||||
{
|
||||
"file": "src/main/ssh-service.cjs",
|
||||
"lines": 336,
|
||||
"branches": 43,
|
||||
"functions": 69,
|
||||
"ipcHandlers": 0,
|
||||
"responsibilities": [
|
||||
"deployment",
|
||||
"git",
|
||||
"security",
|
||||
"updates"
|
||||
],
|
||||
"hotspotScore": 63
|
||||
},
|
||||
{
|
||||
"file": "src/main/deploy-key-lifecycle-service.cjs",
|
||||
"lines": 192,
|
||||
@@ -415,20 +430,6 @@
|
||||
],
|
||||
"hotspotScore": 55
|
||||
},
|
||||
{
|
||||
"file": "src/main/diagnostics-service.cjs",
|
||||
"lines": 357,
|
||||
"branches": 34,
|
||||
"functions": 50,
|
||||
"ipcHandlers": 0,
|
||||
"responsibilities": [
|
||||
"deployment",
|
||||
"git",
|
||||
"security",
|
||||
"updates"
|
||||
],
|
||||
"hotspotScore": 54
|
||||
},
|
||||
{
|
||||
"file": "src/renderer/actions/inventory.js",
|
||||
"lines": 186,
|
||||
@@ -668,7 +669,7 @@
|
||||
},
|
||||
{
|
||||
"file": "src/main/unraid-deploy-key-host.cjs",
|
||||
"lines": 77,
|
||||
"lines": 80,
|
||||
"branches": 7,
|
||||
"functions": 22,
|
||||
"ipcHandlers": 0,
|
||||
|
||||
Reference in New Issue
Block a user