Stop starting Unraid's Node CLI on every Partnership render
`unraid-api apikey` costs 1.98s and ran once per render just to answer whether a key exists. Cached for a minute — still read from the key store, so a deletion still shows, a minute later rather than instantly. Partner probes are multiplexed at the same time.
This commit is contained in:
@@ -189,11 +189,24 @@ function vv_pt_ts_peers(): array {
|
|||||||
|
|
||||||
// ── SSH helper — run a single command on a remote host ────────────────────────
|
// ── SSH helper — run a single command on a remote host ────────────────────────
|
||||||
|
|
||||||
|
// Multiplexed, because this page makes several of these per render — a state read per partner,
|
||||||
|
// plus whatever a card asks for — and each one was paying a full handshake to a node across a real
|
||||||
|
// internet hop. Measured at about two seconds per call against 0.09s once a master is up.
|
||||||
|
//
|
||||||
|
// The socket lives in tmpfs so a reboot cannot inherit a stale one, and the path is kept short: a
|
||||||
|
// unix socket path is capped near 108 characters and ssh appends the user and host to this.
|
||||||
function vv_pt_ssh(string $ip, string $sshKey, string $cmd, int $timeout = 4): string {
|
function vv_pt_ssh(string $ip, string $sshKey, string $cmd, int $timeout = 4): string {
|
||||||
if (!$ip || !$sshKey || !file_exists($sshKey)) return '';
|
if (!$ip || !$sshKey || !file_exists($sshKey)) return '';
|
||||||
|
|
||||||
|
$sock = rtrim(VV_CACHE_ROOT, '/') . '/ssh';
|
||||||
|
if (!is_dir($sock)) @mkdir($sock, 0700, true);
|
||||||
|
|
||||||
$full = sprintf(
|
$full = sprintf(
|
||||||
'ssh -i %s -o ConnectTimeout=%d -o StrictHostKeyChecking=no -o BatchMode=yes root@%s %s 2>/dev/null',
|
'ssh -i %s -o ConnectTimeout=%d -o StrictHostKeyChecking=no -o BatchMode=yes'
|
||||||
escapeshellarg($sshKey), $timeout, escapeshellarg($ip), escapeshellarg($cmd)
|
. ' -o ControlMaster=auto -o ControlPersist=60s -o ControlPath=%s'
|
||||||
|
. ' root@%s %s 2>/dev/null',
|
||||||
|
escapeshellarg($sshKey), $timeout, escapeshellarg($sock . '/pt-%h'),
|
||||||
|
escapeshellarg($ip), escapeshellarg($cmd)
|
||||||
);
|
);
|
||||||
return shell_exec($full) ?: '';
|
return shell_exec($full) ?: '';
|
||||||
}
|
}
|
||||||
@@ -513,11 +526,27 @@ function vv_pt_nodes(): array {
|
|||||||
$apiKeySet = false;
|
$apiKeySet = false;
|
||||||
$apiKeyPreview = '';
|
$apiKeyPreview = '';
|
||||||
if ($isMe) {
|
if ($isMe) {
|
||||||
|
// Cached for a minute, because `unraid-api apikey` is not a file read — it starts
|
||||||
|
// Unraid's Node CLI, measured at 1.98s, and it ran on every render of this page. That
|
||||||
|
// was the single largest cost in assembling it, and this page is the one that opens
|
||||||
|
// the mesh chat, so it was two seconds in front of a conversation every time.
|
||||||
|
//
|
||||||
|
// Still reads the key store rather than the conf, so a key deleted in Unraid's own UI
|
||||||
|
// is still reflected — a minute later rather than instantly, which is the trade. The
|
||||||
|
// preview is eight characters of a key that changes when someone deliberately rotates
|
||||||
|
// it; nobody is watching it to the second.
|
||||||
|
$apiData = vv_cache_read('pt_apikey', 60);
|
||||||
|
if ($apiData === null) {
|
||||||
$hn = trim((string)shell_exec("hostname -s 2>/dev/null | sed 's/^[Uu][Nn][Rr][Aa][Ii][Dd]-//'")) ?: 'Varaverk';
|
$hn = trim((string)shell_exec("hostname -s 2>/dev/null | sed 's/^[Uu][Nn][Rr][Aa][Ii][Dd]-//'")) ?: 'Varaverk';
|
||||||
$keyName = 'Varaverk ' . $hn;
|
$keyName = 'Varaverk ' . $hn;
|
||||||
$apiOut = shell_exec('/usr/local/sbin/unraid-api apikey --name ' . escapeshellarg($keyName) . ' --json </dev/null 2>/dev/null');
|
$apiOut = shell_exec('/usr/local/sbin/unraid-api apikey --name ' . escapeshellarg($keyName) . ' --json </dev/null 2>/dev/null');
|
||||||
$apiData = json_decode(trim($apiOut ?? ''), true);
|
$decoded = json_decode(trim($apiOut ?? ''), true);
|
||||||
if (is_array($apiData) && !empty($apiData['key'])) {
|
// Cached either way. A host with no key would otherwise pay the two seconds on
|
||||||
|
// every render forever, which is the case that needs the cache most.
|
||||||
|
$apiData = is_array($decoded) ? $decoded : [];
|
||||||
|
vv_cache_write('pt_apikey', $apiData);
|
||||||
|
}
|
||||||
|
if (!empty($apiData['key'])) {
|
||||||
$apiKeySet = true;
|
$apiKeySet = true;
|
||||||
$apiKeyPreview = substr($apiData['key'], 0, 8) . '...' . substr($apiData['key'], -4);
|
$apiKeyPreview = substr($apiData['key'], 0, 8) . '...' . substr($apiData['key'], -4);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user