fix(issue-17): review R1 - a finalize wait is measured on the monotonic clock, like bash's sleep

codex, PR #51 round 1. wrapper._sleep computed the span and the remainder
with time.time(). The broker re-observation (up to 3 s) and the disk-heartbeat
grace (1 s) use it, so a wall clock stepped back during the wait stretched it
by the step: on a mocked clock stepped back 10 s, an already completed job was
seen after 11 s / 13 s instead of 1 s / 3 s. The old bash ran `sleep 1` /
`sleep "$left"`, which do not follow the wall clock.

_sleep now measures on time.monotonic(). The deadline (START_TIME + TIMEOUT),
the evidence window and event timestamps stay on the wall clock (_now), as in
the bash.

test_u_a_wait_is_not_stretched_by_a_wall_clock_step_back (1 s, 3 s) swaps the
module's time for a clock stepped back 10 s during the first sleep; on the
previous code it measures 11.0 / 13.0 and fails. The comparison test and the
finalize-related behaviour tests (issue33, issue18, issue14) on macOS /
Python 3.9: 321 passed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VCgu9Fa9iT7TbJUSzdq4Ff
This commit is contained in:
GodopuandClaude Opus 5.5 committed 2026-10-08 00:53:09 +09:00
1 parent 518bedac5d
commit 4c86107846
2 files changed
+43 -3

No files matched your search

+6 -3
View File
@@ -143,11 +143,14 @@ def _check_owner(a: argparse.Namespace) -> None:
def _sleep(a: argparse.Namespace, seconds: float) -> None:
"""time.sleep that looks at the wrapper every 0.5 s."""
end = time.time() + seconds
"""time.sleep that looks at the wrapper every 0.5 s. The span is measured
on the monotonic clock, as bash's `sleep N` is: a wall clock stepped back
during the wait must not stretch it (review R1, codex). Deadlines stay on
the wall clock (_now)."""
end = time.monotonic() + seconds
while True:
_check_owner(a)
left = end - time.time()
left = end - time.monotonic()
if left <= 0:
return
time.sleep(min(left, 0.5))