2.8 KiB
2.8 KiB
The test_emacs flake
The symptom
One run of dune test --root . exited 1; the next run on the same tree exited 0.
FAIL the client notices a stop nobody asked about
FAIL and the modeline says so, with the condition
Error: error ("flan dev: cannot reconnect to /tmp/build_997a01_dune/flan-emacs-dev.sock: make client process failed: Connection refused, ...")
What the error text already rules out
Two mechanisms have produced something like this here before: a genuine
listen/connect ordering bug, and a five-second await against a cold
llc-and-link. Neither fits this text, and the reason is in the branches:
- A 20s poll deadline that simply expired leaves the connection live.
The two
FAILs would print andflan-dev-restartswould then succeed. There would be noError:line at all. - The daemon exiting — the child program finishing,
servereturningclosed, or any OCaml exception — runsFun.protect's finally inDev.two_process, which unlinks the socket. The client then takes the(not (file-exists-p ...))branch and says "nothing is listening on ...; startflan dev program.flanagain". A different message. Connection refusedon a unix socket needs the path to exist and no socket in listen state behind it. Intwo_process(lib/dev.ml:2514-2526)bindandlistenare adjacent, nothing else ever creates that path, and the only close of the listening fd is in the same finally that unlinks. So it is reachable essentially one way: the daemon died without running its finally — that is, it was killed by a signal.
The machine was loaded (several compiler lanes building at once) and /tmp
filled to 100% the day before, so the OOM killer is the first candidate.
The plan
- Fix the observability first.
test_emacs.mlthrows away the one fact that discriminates: the cleanupwaitpidmatches| _ -> trueand drops the status, and the temporary files are removed before the exit code is checked, so the program's output is gone by the time anyone looks. - Reproduce by running
_build/default/test/test_emacs.exein a loop under artificial load, recording the daemon's wait status,df /tmpanddmesg | taileach iteration. - Fix the mechanism the evidence names.
- Sweep the siblings —
test_repl.ml,test_dev.ml,test_cider.ml. What they share withtest_emacs.mlis the discarded wait status, not a missing connect retry: they already have retryingconnecthelpers.
Open questions
lib/cimport.ml:1138still spells its owncachedirunder$TMPDIR, which NEXT.md:694 flags as the last remnant of the cold-cache bug. Another lane holds that file. It is both a per-run cold cache and a plausible filler of/tmp.
Status
Stub. Investigation in progress.