Stop the media seed from holding the onboard, and therefore the partnership, open for weeks

A first seed is ~28 TB behind a 12.5 MB/s bwlimit, and it ran inline as Step 9d, so the
phase-2 flag every status reader depends on was written only after it finished.
This commit is contained in:
Gmer4Lfe
2026-08-17 07:40:00 -04:00
parent 9d2610a911
commit ad623353bc
6 changed files with 466 additions and 61 deletions
+59
View File
@@ -230,6 +230,64 @@ function vv_pt_remote_system(string $ip, string $sshKey): array {
];
}
// ── Media seed progress ───────────────────────────────────────────────────────
//
// Onboard Step 13 dispatches Rsync/media_seed.sh detached, because a first seed of a full
// media library is a multi-week transfer and used to hold the onboard — and therefore the
// phase-2 flag, and therefore this whole page — open for the duration.
//
// Detaching it means nothing on screen would mention it at all unless something reads its
// job record, which is what this does. The seed is a push from this host to the partner, so
// it is rendered on the partner's card even though every byte of evidence for it is local.
//
// Returns [] when there has never been a seed. A stale "running" record whose pid is gone is
// reported as stopped rather than running: a record is not a process.
function vv_pt_media_seed(): array {
$stat = '/var/log/varaverk/Rsync/media_seed.json';
$log = '/var/log/varaverk/Rsync/media_seed.log';
if (!is_file($stat)) return [];
$j = json_decode((string)file_get_contents($stat), true);
if (!is_array($j)) return [];
$status = (string)($j['status'] ?? '');
$pid = (int)($j['pid'] ?? 0);
if ($status === 'running' && (!$pid || !is_dir("/proc/$pid"))) {
$status = 'stopped';
}
$share = '';
$line = '';
if (is_file($log)) {
// rsync --info=progress2 rewrites one line with \r, so the tail is read as bytes and
// split on both terminators — splitting on \n alone yields a single enormous "line"
// holding every progress repaint of the current file.
$fh = fopen($log, 'r');
if ($fh) {
fseek($fh, 0, SEEK_END);
$size = ftell($fh);
fseek($fh, max(0, $size - 65536));
$tail = (string)fread($fh, 65536);
fclose($fh);
$parts = preg_split('/[\r\n]+/', $tail) ?: [];
for ($i = count($parts) - 1; $i >= 0; $i--) {
$p = trim($parts[$i]);
if ($p === '') continue;
if ($line === '') $line = $p;
if (preg_match('/Seeding:\s*(\S+)/', $p, $m)) { $share = $m[1]; break; }
}
}
}
return array_filter([
'status' => $status,
'start' => isset($j['start']) ? (int)$j['start'] : null,
'end' => isset($j['end']) ? (int)$j['end'] : null,
'share' => $share,
'line' => mb_substr($line, 0, 160),
], fn($v) => $v !== null && $v !== '');
}
// ── Per-node data ─────────────────────────────────────────────────────────────
function vv_pt_nodes(): array {
@@ -362,6 +420,7 @@ function vv_pt_nodes(): array {
'api_key_set' => $apiKeySet,
'api_key_preview' => $apiKeyPreview,
'metrics' => $metrics,
'media_seed' => $isMe ? [] : vv_pt_media_seed(),
];
}
return $nodes;