#326: state primary's real consequence, and write down the denominator
The merged javadoc said a changed primary.terminal leaves a lead 'unresolved as primary until a restart'. That over-claims. CB-532 made the pin deprecated: identity comes from leaders:/leadScan:, and Fleetd.java:511 warns about the pin at startup. A changed pin still needs a restart, but for the fallback nudge destination, the deprecated identity path, and pushReminders/pushBackoffMs - not for a lead that uses leaders:. Also record what I measured. FleetConfig has 22 top-level components; four are named nowhere in ConfigRef. memberCredentials and memberLoginShell are hot and correctly absent (both read live off config.get() at spawn). health and coordinator are undecided, not hot. 'Absent' looks the same for both kinds, and twice now the forgotten kind hid among the correct kind.
This commit is contained in:
@@ -45,8 +45,12 @@ import java.util.function.Supplier;
|
||||
* {@link #changedDeferredKeys}), {@code primary:} (fleetd #326 — {@code Fleetd.java:506, 519,
|
||||
* 520} read {@code cfg.primary()} only off the startup snapshot to build {@code
|
||||
* PrimaryRegistry} and size {@code ReplyPushLoop}'s reminder cap/backoff, and neither is
|
||||
* rebuilt on reload; a lead whose pinned terminal changed under a running daemon stays
|
||||
* unresolved as primary until a restart), {@code configReload:} (fleetd #326 — {@code
|
||||
* rebuilt on reload. Say the consequence exactly: {@code primary.terminal} is DEPRECATED
|
||||
* (CB-532, and {@code Fleetd.java:511} warns about it at startup) — a lead's identity comes
|
||||
* from {@code leaders:}/{@code leadScan:}, so changing this pin does not demote or promote a
|
||||
* lead that uses those. What a changed pin still does not take effect on until a restart is
|
||||
* the fallback nudge destination the pin remains, the deprecated identity path for an operator
|
||||
* who still relies on it, and {@code pushReminders}/{@code pushBackoffMs}), {@code configReload:} (fleetd #326 — {@code
|
||||
* Fleetd.java:679-680} read it only at startup to decide whether to build a {@code
|
||||
* ConfigWatcher} at all and with what interval; the watcher that would apply a later change is
|
||||
* itself built once, so a running watcher keeps polling on its original enabled flag and
|
||||
@@ -73,6 +77,24 @@ import java.util.function.Supplier;
|
||||
* listening.</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p><strong>The denominator, measured on 2026-09-04 (fleetd #326).</strong> {@code FleetConfig} has
|
||||
* 22 top-level record components. Four of them are named nowhere in this file, and the reason
|
||||
* differs per key, so do not read "absent" as "forgotten":
|
||||
* <ul>
|
||||
* <li>{@code memberCredentials} and {@code memberLoginShell} are <strong>hot</strong> and
|
||||
* correctly absent — both are read live off {@code config.get()} at spawn time
|
||||
* ({@code Fleetd.java:198, 205, 729} and {@code HerdrPeerLauncher#configuredMemberLoginShell}),
|
||||
* so a reload takes effect on the next spawn with no entry needed here.</li>
|
||||
* <li>{@code health} and {@code coordinator} are <strong>undecided</strong>, not hot. Each is read
|
||||
* both ways at different sites, so neither fits the three classes above as a whole key. Until
|
||||
* that is settled a reload touching them reports a bare "config reloaded", which under-claims.
|
||||
* Deciding it is what a top-level coverage checker (the {@link ConfigRefProfileCoverageTest}
|
||||
* shape, one level up) is waiting on — without it, such a checker cannot express the answer.</li>
|
||||
* </ul>
|
||||
* The point of writing the count down: "not mentioned in this file" looks identical for a key that
|
||||
* is correctly hot and for a key nobody triaged. Twice now — {@code worktreeGroup} (#323) and
|
||||
* {@code primary}/{@code configReload} (#326) — the second kind hid among the first.
|
||||
*
|
||||
* <p><strong>A cold change refuses the whole reload.</strong> Not the hot half applied and the cold
|
||||
* half warned about: that would leave the running daemon in a state matching no file on disk, which
|
||||
* is the worst thing a reload can do to an operator debugging one. Refusing keeps the invariant that
|
||||
@@ -246,7 +268,9 @@ public final class ConfigRef implements Supplier<FleetConfig> {
|
||||
}
|
||||
// fleetd #326: Fleetd.java:506, 519, 520 read cfg.primary() only off the startup snapshot
|
||||
// (PrimaryRegistry's pinned terminal, ReplyPushLoop's reminder cap and backoff) — neither is
|
||||
// rebuilt on reload, so a changed pin needs a restart before a lead resolves as primary again.
|
||||
// rebuilt on reload, so a changed value needs a restart. Note what it does NOT mean:
|
||||
// primary.terminal is deprecated (CB-532), identity comes from leaders:/leadScan:, so a lead
|
||||
// using those is unaffected by this pin either way. See the class doc for the exact scope.
|
||||
if (!Objects.equals(old.primary(), fresh.primary())) {
|
||||
changed.add("primary");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user