perf(daemon): memoize the external debug.log miss
When following the debug.log of a node this session did not launch, every poll re-read the last 2 MB of the file and re-scanned it for the process banner. If that node logs to its console instead, the banner is never there, so the full re-scan repeated on every poll for the life of the process. - A miss is now remembered by pid and file size: if nothing has changed since the last miss, or the file is growing but the backoff has not elapsed, the scan is skipped. - The retry schedule re-scans quickly during a fresh-node grace window (the banner flushes a beat after the pid appears) and then backs off from 4 s, doubling to a 60 s cap. The memo is cleared on a successful tie and when the followed process goes away. Tests: the retry delay is fast within the grace window and then steps 4, 8, 16 s up to the 60 s cap. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -141,6 +141,17 @@ inline bool shouldConfirmStop(bool stopsDaemon, const DaemonBusyTracker& tracker
|
||||
return stopsDaemon && (tracker.rebuilding() || rpcBusyWhileAlive);
|
||||
}
|
||||
|
||||
// Retry schedule after failing to find a pid's banner in debug.log: re-scan fast during the fresh-node grace
|
||||
// window, then back off 4 s doubling to a 60 s cap. `backoff` is the caller's running state (0 until grace ends).
|
||||
inline double nextExternalLogRetryDelay(double ageSinceMiss, double& backoff,
|
||||
double graceWindow = 15.0, double fast = 2.0,
|
||||
double base = 4.0, double cap = 60.0)
|
||||
{
|
||||
if (ageSinceMiss < graceWindow) return fast;
|
||||
backoff = (backoff < base) ? base : (backoff * 2.0 < cap ? backoff * 2.0 : cap);
|
||||
return backoff;
|
||||
}
|
||||
|
||||
/**
|
||||
* Where to start feeding a DaemonBusyTracker from the last `window` of the debug.log of a node someone else
|
||||
* started at `processStartUtc` (UTC seconds). Only lines that process wrote count: a node started with
|
||||
|
||||
Reference in New Issue
Block a user