Cache the watchdog payload, and stop reading trailing comments as conf values
The tab collected over SSH on every 30s poll — 8.3s a load with HOST2 down. vv_parse_conf_scalar() captured to end of line, so a commented toggle parsed as "true # HOST2 back online": every threshold read right because (int) stops at the first non-digit, and 38 booleans read wrong. The Fallback tab has been showing failover disabled while it was on.
This commit is contained in:
@@ -56,6 +56,18 @@ require_once __DIR__ . '/partnership.php';
|
||||
|
||||
// Watchdog tab data helpers
|
||||
|
||||
// Rows in system_watchdog_state.db that are bookkeeping, not strikes. The file is a flat key/value
|
||||
// store shared by the counters and the watchdog's own liveness record, so the only thing separating
|
||||
// the two is knowing which is which — there is no marker in the format.
|
||||
//
|
||||
// watchdog_cycle is a unix timestamp, written every cycle by stability_watchdog.sh:883 for
|
||||
// docker_watchdog's stale-state guard. Published as a strike it reads as 1.7 billion of them.
|
||||
//
|
||||
// Add to this list, never to a shape test: a strike count and a timestamp are both positive
|
||||
// integers, and a threshold like "bigger than a billion means it is a clock" is a rule that works
|
||||
// until it doesn't and fails silently in the direction of hiding a real strike.
|
||||
const VV_WD_SYS_BOOKKEEPING = ['watchdog_cycle'];
|
||||
|
||||
// ── Conf array parser (bash arrays) ──────────────────────────────────────────
|
||||
|
||||
function vv_wd_bash_array(string $raw, string $varname): array {
|
||||
@@ -213,11 +225,19 @@ function vv_wd_local_states(string $restartLogPath): array {
|
||||
$strikes[$k] = (int)$v;
|
||||
}
|
||||
|
||||
// Stability strikes: everything in sys state that isn't a flag key
|
||||
// Stability strikes: everything in sys state that is actually a strike.
|
||||
//
|
||||
// The old guard was `!str_contains($k, '=')`, written on the belief that the bookkeeping rows
|
||||
// in system_watchdog_state.db keep their `=` inside the key because the file mixes separators
|
||||
// — `ram:0` and `sshd:0` beside `kernel_oops_count=0` and `watchdog_cycle=...`. They do not:
|
||||
// vv_wd_parse_kv() splits on both, so the guard never matched anything and every bookkeeping
|
||||
// row was published as a strike. watchdog_cycle is a unix timestamp written once per cycle by
|
||||
// stability_watchdog.sh:883 as a liveness heartbeat, so the Stability card was drawing
|
||||
// "watchdog cycle — 1786716931" next to a limit of 2.
|
||||
$sysStrikes = [];
|
||||
foreach ($sys as $k => $v) {
|
||||
if (!str_contains($k, '=') && (int)$v > 0)
|
||||
$sysStrikes[$k] = (int)$v;
|
||||
if (in_array($k, VV_WD_SYS_BOOKKEEPING, true)) continue;
|
||||
if ((int)$v > 0) $sysStrikes[$k] = (int)$v;
|
||||
}
|
||||
|
||||
// Growth baseline info (container count + age in seconds)
|
||||
@@ -322,9 +342,12 @@ function vv_wd_remote_data(string $ip, string $sshKey, string $restartLogPath):
|
||||
if ($k !== 'daemon_strikes' && $k !== 'daemon_restarted_flag' && (int)$v > 0)
|
||||
$strikes[$k] = (int)$v;
|
||||
}
|
||||
// Same exclusion as the local path above — a partner's heartbeat is no more a strike than
|
||||
// this host's. The two builders are maintained together.
|
||||
$sysStrikes = [];
|
||||
foreach ($sys as $k => $v) {
|
||||
if (!str_contains($k, '=') && (int)$v > 0) $sysStrikes[$k] = (int)$v;
|
||||
if (in_array($k, VV_WD_SYS_BOOKKEEPING, true)) continue;
|
||||
if ((int)$v > 0) $sysStrikes[$k] = (int)$v;
|
||||
}
|
||||
|
||||
$baselineCount = (int)($hdr['BASELINECOUNT'] ?? 0);
|
||||
@@ -420,6 +443,12 @@ function vv_wd_all(): array {
|
||||
'net_wd_enabled' => vv_wd_scalar($masterRaw, 'NETWORK_WATCHDOG_ENABLED') !== 'false',
|
||||
'npm_strike_lim' => (int)(vv_wd_scalar($masterRaw, 'NETWORK_WATCHDOG_NPM_STRIKE_LIMIT') ?: 2),
|
||||
'ts_check' => vv_wd_scalar($masterRaw, 'NETWORK_WATCHDOG_CHECK_TAILSCALE') !== 'false',
|
||||
// Conf cache watchdog. It has no state of its own to report because it writes none until
|
||||
// it runs, and it does not run: conf_cache_watchdog.sh:145-146 exits on either of these
|
||||
// being off. Both gates ship so the page can say "off, and here is which switch", rather
|
||||
// than omit a member of SYSTEM_WATCHDOG_SCRIPTS entirely and let its absence read as fine.
|
||||
'fallback_on' => vv_wd_scalar($masterRaw, 'FALLBACK_ENABLED') === 'true',
|
||||
'conf_sync_on' => vv_wd_scalar($masterRaw, 'CONF_SYNC_ENABLED') !== 'false',
|
||||
];
|
||||
|
||||
// SSH key from current host conf
|
||||
|
||||
Reference in New Issue
Block a user