Heartbeat before each poll so a slow poll doesn't false-trip the watchdog
The isolated Telegram poller child emitted its liveness heartbeat only between polls (poller-sleep/heartbeat runs after tg-bot-tick returns). A single poll that blocks longer than the watchdog stale threshold (getUpdates runs over a blocking native TLS read with no timeout) thus left the child silent past the window and the watchdog killed it though it was alive and mid-request -- the recurring kill right after a fresh start, where the first poll's cold TLS handshake is slowest.
Emit a heartbeat immediately BEFORE each poll so the watchdog window resets at the start of the blocking call, giving every poll the full stale threshold to return. A literal heartbeat during the poll is impossible: the child is a single-threaded no-scheduler process and a blocking native read freezes every goroutine (the reason polling is process-isolated). A poll that truly exceeds the threshold is still a genuine wedge and is still killed + respawned.
src/courier/poller.sgl | 17 +++++++++++++++++
1 file changed, 17 insertions(+)src/courier/poller.sglmodified
(log-info "Telegram poller child started" pid: (process-id)) (let loop ((backoff *error-backoff-initial*)) ;; Heartbeat IMMEDIATELY BEFORE the (blocking) poll so the ;; supervisor's liveness window resets right at the start of ;; the risky call. tg-bot-tick runs over a blocking native ;; TLS read with no timeout; heartbeating only *between* ;; polls (poller-sleep/heartbeat, below) lets a single slow ;; poll straddle the stale threshold, so the watchdog ;; false-positive-kills a child that is alive and mid-request ;; -- the fresh-start kill this fix targets, where the first ;; poll (cold TLS handshake/DNS) is slowest. We cannot ;; heartbeat *during* the poll: a blocking native freezes the ;; child's scheduler (the reason polling is process-isolated ;; at all), so the pre-poll heartbeat is the strongest ;; available decoupling -- it gives each poll the full stale ;; threshold to return before it looks wedged. (poller-emit-line! *heartbeat-line*) (when (poller-parent-gone?) (exit 0)) (let ((ok? (guard (e (else (log-error (format "Poll loop error: ~a" e)) #f))