row 269 (264b, #1774): BUILD.md answers sage-2750 on the recover() change; the survivor log names its pids
The section "recover() change, for a design read" covers three things, with
file:line against aca16404c. Every leftover is still bound and ended as
host-lost, and a survivor only refuses legacy-run-live while it lives. The
5 s wait applies only in the bwrap kill branch. No old test's expected value
changes. The fallback is to revert to the base recover() and leave the
refusal untested. The survivor log line now names the outer and runner pids
so an operator can clear it, and the new test's log assertion matches.
This commit is contained in:
1 parent
3d29876dfb
commit
9221786228
3 files changed
+52
-2
No files matched your search
@@ -321,6 +321,56 @@ Written before the first run, which waits for Sage's CLEAR.
|
||||
killed. M10-M12 cover it. The registry and pre-recover leftover terms stay. A launching host
|
||||
can't reach them for a thread instance (check() refuses `session-required` first, and listen()
|
||||
runs recover() first), but they cost nothing.
|
||||
|
||||
### recover() change, for a design read (sage-2750)
|
||||
|
||||
Sage asked for this because recover() predates the row. Lines are launcher.mjs at 3d29876df plus
|
||||
the log-line edit after it, against aca16404c:947-976.
|
||||
|
||||
- What stays the same: every leftover is still bound and ended as host-lost (:1030-1040, base
|
||||
:963-973). The survivor push (:1026-1029) comes before the bind, and the loop carries on past it,
|
||||
so a kept leftover isn't left unended. Its bus run ends and its role is released, as in the base.
|
||||
The kill is unchanged too: SIGKILL only to a live outer pid whose cmdline is bwrap (:1018-1021,
|
||||
base :956-959).
|
||||
- What changes:
|
||||
1. The wait after the kill runs while the outer pid or the runner still runs (:1023). In the
|
||||
base it waited on the outer pid only (base :961).
|
||||
2. A leftover where either still runs after that goes on `survivors` and is logged (:1026-1029).
|
||||
3. check() counts a survivor only while it still runs (:309, `liveRun` at :255).
|
||||
- a. Nothing in this row kills a kept leftover's runner. The base didn't either: it ended the run
|
||||
and let the runner go on, unseen. The run is still ended (:1038), so the runner holds no role.
|
||||
Its capability died with the old broker (:1004-1008). The only thing a survivor does is refuse
|
||||
`legacy-run-live` for sessions of its instance while it lives, and each refusal is a `refused`
|
||||
launch record. For an operator, the log line names the run, the outer pid and the runner pid
|
||||
(:1028). Killing that pid clears it. check() re-reads liveness on each pass (:309), so the next
|
||||
tick starts the session with no host restart. If bindLaunch refuses (:1032-1036), the run stays
|
||||
unended and logged, as in the base (base :965-969). The survivor entry doesn't change that.
|
||||
- b. The 5 s wait only applies inside the kill branch (:1018-1024), so only to a leftover whose
|
||||
outer bwrap was still alive. A leftover with nothing running doesn't wait, and nor does one
|
||||
whose outer pid is gone: neither enters the branch. The wait ends as soon as both processes are
|
||||
gone. The base already waited up to 5 s in the same branch. It can now last longer only if the
|
||||
runner outlives its outer pid. With `--unshare-pid` and `--die-with-parent` the runner dies when
|
||||
the namespace goes.
|
||||
- c. Old tests that run recover() with a launching host and a leftover:
|
||||
- launcher.test.mjs:885-943, the "host that died hard" pair. It asserts the outer pid and the
|
||||
runner are gone right after setup (:917-918), the host-lost log (:919), one session.ended
|
||||
(:920-922), one end record (:924), an empty sessions.json (:925), and then "already ended" for
|
||||
a leftover whose processes are dead (:937-941). None of these expected values change.
|
||||
Waiting on the runner makes :918 hold sooner, not later. The new log line can appear only if
|
||||
a process outlives 5 s, which would already fail :917-918. The dead-process third host takes
|
||||
no wait and logs no survivor.
|
||||
- launcher.test.mjs:950-971 (`--no-launch`) returns before the loop (:1012-1015). It's
|
||||
unchanged.
|
||||
- stack-release.test.mjs:1928 writes `{pid: process.pid}` with no start times. `liveRun` is
|
||||
false for it, and that test reads it through bus status, not recover().
|
||||
- verbs.test.mjs:213 and the seat tests build a Registry with no launcher, so they aren't
|
||||
affected.
|
||||
|
||||
No expected value in an old test changes, so nothing goes to Mos under mos-1272 for this. If a
|
||||
run shows otherwise, I stop and send it before any change.
|
||||
- Fallback, if Duckworth or Sage doesn't accept this: revert recover() and check() to the base
|
||||
behaviour, keeping only the sessionless check over the registry, the pre-recover leftovers and
|
||||
bwrap survivors. Drop the legacy-run-live test and M10-M12, and name the untestable path here.
|
||||
- N1 (refusedOnce pins `actor_run`) changes a pre-existing test. Under mos-1290 term 5 it goes to Mos
|
||||
first, so the edit stays out of the code commit until Mos rules.
|
||||
|
||||
|
||||
@@ -1025,7 +1025,7 @@ export function createLauncher({
|
||||
// Row 269 (Q2): the session or its runner outlived the kill, or wasn't a session to kill.
|
||||
if (liveRun(s)) {
|
||||
survivors.push(s);
|
||||
log(`run ${s.run} (${s.instance}) from an earlier host still runs`);
|
||||
log(`run ${s.run} (${s.instance}) from an earlier host still runs (pid ${s.pid}, runner ${s.runnerPid}): no session of ${s.instance} starts until it exits`);
|
||||
}
|
||||
try {
|
||||
await host.bindLaunch({ business: b.id, role: s.instance, run: s.run, harness: s.harness, pid: s.pid, startTime: s.startTime, ...(s.thread ? { thread: s.thread } : {}), ...(s.session ? { session: s.session } : {}) });
|
||||
|
||||
@@ -306,7 +306,7 @@ test("REQ-THREAD-2 REQ-LAUNCH-1 a session start refuses legacy-run-live while an
|
||||
const runnerStartTime = await until(() => startTimeOf(runner.pid));
|
||||
new Registry(f.dataRoot).add({ business: "acme", instance: "assistant", thread: "th-old", run: "run-left", harness: "pi", pid: 2 ** 22 + 7, startTime: "gone", runnerPid: runner.pid, runnerStartTime });
|
||||
const host = await start(t, prepared);
|
||||
assert.ok(host.logs.includes("run run-left (assistant) from an earlier host still runs"), host.logs.join("\n"));
|
||||
assert.ok(host.logs.includes(`run run-left (assistant) from an earlier host still runs (pid ${2 ** 22 + 7}, runner ${runner.pid}): no session of assistant starts until it exits`), host.logs.join("\n"));
|
||||
const { A, S } = twoSessions(host.call);
|
||||
|
||||
const toS = send(host.call, A, S, "for S");
|
||||
|
||||
Reference in new issue
Block a user