By: Tom Sydney Kerckhove <syd@cs-syd.eu>
Keep the host alive while it has workers to lose A host that finds it can no longer fork used to exit, and every worker it had forked dies with it. That threw away warm workers part-way through their attributes to report a condition that only costs the run its next fork: each of those attributes then had to be evaluated again, on a worker that had to load the flake for itself first, and an attribute unlucky enough to lose a second worker is reported as an error rather than discovered. It now says so and idles instead, once it has forked anything, and the coordinator stops asking it for workers rather than killing it. A host that never got as far as ready has no workers to lose and is still replaced, which is what makes a fetched flake cost one extra load rather than one per worker. Killing the pool at the end of a run goes through the host for the same reason: its workers die with it, so they need no signal of their own, and a pid this process never waited for is one it should not be signalling at all. The host reaps what it forks, so such a pid can already mean another process. Two smaller things in the same place: a "prime" request whose payload is not an attribute path is answered rather than thrown (the guard above it only caught malformed JSON, so a type error escaped and abandoned the run), and the "exit" request the coordinator never sends is gone. The new check kills the host mid-run and asserts every output is still reported. What is not covered is the host bowing out on its own: that happens when nix starts a thread, which a hermetic test cannot make it do.