diff --git a/README.md b/README.md index 28bad38..dd58e61 100644 --- a/README.md +++ b/README.md @@ -410,7 +410,10 @@ runner, `KeepAlive` restarts it and it passes again within seconds. Anywhere else, `factory lease grant` and `factory watchdog ensure` start one, and `factory watchdog once`, which `doctor` carries, says `NO RUNNER` at exit 4 for as long as a live lease has none. A dead runner restarts instead of being -reported, and a lease it left standing is the status quo. The lease is what +reported, and a lease it left standing is the status quo. A runner that starts +without a live lease says `no live lease` on fd 1 and exits, which is why the +launchd log of a machine nobody has granted anything reads as idle rather than +as empty, and empty is what a crash looks like too. The lease is what you switch: `grant` and it runs, `revoke` and it stops, and `shift-over` is the log's last line when a timed lease ran out. diff --git a/libexec/factory-watchdog b/libexec/factory-watchdog index 326b53d..64f3c73 100755 --- a/libexec/factory-watchdog +++ b/libexec/factory-watchdog @@ -536,11 +536,24 @@ run) fi case "$rc" in 1) - # The lease ended. A runner that passed under it says so, once, so the - # log's last line is the end of the shift and not merely its last pass; - # one that never saw a lease — started after the expiry, or racing a - # revoke — has nothing to add. No lease, so `note` restores nothing. - [ "$passes" -eq 0 ] || note info "shift-over: lease ended — $passes pass(es) this run" + # The lease ended. A runner that passed under it says so in the log, + # once, so the log's last line is the end of the shift and not merely + # its last pass. No lease, so `note` restores nothing. + # + # One that never saw a lease — started after the expiry, or racing a + # revoke — has nothing for the LOG, since nothing passed and so nothing + # is over. It still owes a line on fd 1. Under launchd this is the + # ORDINARY exit rather than the rare one: `KeepAlive` starts the runner + # again every throttle interval for as long as nobody has granted + # anything, and its stdout is the only window onto a process nobody + # watched start. Silent, `launchctl list` shows `- 0` whether the + # runner is idle for want of a lease or exiting on a bug, and an empty + # log is exactly the claim this refuses to make. + if [ "$passes" -eq 0 ]; then + out_info "watchdog: no live lease — nothing to run" + else + note info "shift-over: lease ended — $passes pass(es) this run" + fi exit 0 ;; 3) diff --git a/test/factory-watchdog.bats b/test/factory-watchdog.bats index 141158c..39fc6d9 100644 --- a/test/factory-watchdog.bats +++ b/test/factory-watchdog.bats @@ -311,15 +311,20 @@ runner_count_is() { [ "$(shift_calls)" -le 4 ] } -@test "a runner that never saw a lease adds nothing to the log" { +@test "a runner that never saw a lease says so on fd 1, and adds nothing to the log" { # Started after the expiry — launchd restarting it, or `ensure` racing a - # revoke. Nothing passed, so nothing is over. + # revoke. Nothing passed, so nothing is over and the log gains nothing. The + # line is still owed: under launchd this is the exit taken every throttle + # interval for as long as nobody has granted anything, and a silent one + # leaves `launchctl list` reading the same for an idle runner and a broken + # one. lease 1 3600 log_aged 60 sleep 2 - run "$WD" run + run --separate-stderr "$WD" run [ "$status" -eq 0 ] - [ -z "$output" ] + [[ "$output" == *"no live lease"* ]] + [ -z "$stderr" ] ! grep -q "shift-over" "$(today_log)" [ "$(shift_calls)" -eq 0 ] }