The orphan-grace scenario's wait no longer proves patience

FLAN_DEV_CLIENT_GRACE dropped from 0.2s to 0.1s, so the daemon's Live
threshold (six graces) is 0.6s instead of 1.2s -- still three ticks
past accept_loop's own 0.2s select granularity, which is where the
margin has to live rather than in the test's own wait. The structural
await scales with it, from three seconds to one: the assertion was
never about the clock, only about serve() sitting in Wire.recv while a
client holds the socket, so the number just had to clear the threshold
with room, not any particular multiple of it.

The other awaits in this test are already ceilings that return the
moment their condition is true, so they cost what the daemon actually
takes and nothing was touched there. A trace of the eval-expr path
elsewhere in this file turned up a second five-second wait, twice over
-- but that one is a documented hang-detection timeout on a program
that structurally cannot reach a frame boundary, the exact shape the
task said to leave alone, so it stayed.
This commit is contained in:
Joseph Ferano 2026-09-19 20:24:19 +07:00
parent 73ab213134
commit 5adc1e2b03

View File

@ -4665,7 +4665,7 @@ let () =
let gpid = let gpid =
Unix.create_process_env flan Unix.create_process_env flan
[| flan; "dev"; "programs/dev-loop.flan"; "-s"; gsock |] [| flan; "dev"; "programs/dev-loop.flan"; "-s"; gsock |]
(Array.append (Unix.environment ()) [| "FLAN_DEV_CLIENT_GRACE=0.2" |]) (Array.append (Unix.environment ()) [| "FLAN_DEV_CLIENT_GRACE=0.1" |])
Unix.stdin gfd Unix.stderr Unix.stdin gfd Unix.stderr
in in
Unix.close gfd; Unix.close gfd;
@ -4684,9 +4684,11 @@ let () =
let r = request c "(:op \"describe\")" in let r = request c "(:op \"describe\")" in
if status r <> "ok" then fail "the orphan-grace daemon: %s" (status r); if status r <> "ok" then fail "the orphan-grace daemon: %s" (status r);
(* Still there while a client is holding the socket, which is the half (* Still there while a client is holding the socket, which is the half
that keeps an editor left open overnight alive. Three seconds against that keeps an editor left open overnight alive. One second against a
a program that is running, so the threshold in force is the longer one program that is running, so the threshold in force is the longer one
6 × 0.2s and the wait is past it with room to spare; a hold 6 × 0.1s = 0.6s, itself three ticks past the accept loop's own 0.2s
poll interval so the number is not fighting the loop's own
granularity and the wait is past it with room to spare; a hold
shorter than that would pass whether or not the clock ran under an shorter than that would pass whether or not the clock ran under an
attached client, and would pin nothing. attached client, and would pin nothing.
@ -4695,7 +4697,7 @@ let () =
[Wire.recv] while the accept loop is not cycling at all. This is the [Wire.recv] while the accept loop is not cycling at all. This is the
guard for the refactor that serves a connection off the accept path guard for the refactor that serves a connection off the accept path
and turns a structural guarantee back into an arithmetic one. *) and turns a structural guarantee back into an arithmetic one. *)
ignore (await ~ms:3000 reaped); ignore (await ~ms:1000 reaped);
if reaped () then if reaped () then
fail "the daemon ended while a client was still connected to it"; fail "the daemon ended while a client was still connected to it";
(* The kill, spelled as the kernel spells it: the fd goes away and (* The kill, spelled as the kernel spells it: the fd goes away and