| Safe Haskell | None |
|---|---|
| Language | GHC2021 |
Ecluse.Core.Worker.Loop
Description
Loop robustness and supervision for the worker.
The loop cannot be killed by a single bad iteration. A failed receive arrives
as the queue handle's typed fault value: the step logs it and backs off (its own
fixed pacing over the typed channel). Residue -- an exception escaping a
dependency's typed contract mid-iteration -- is the supervision combinator's
concern (superviseLoop wraps the step under the
caller-supplied policy), classified per that policy: transient residue is logged
and retried with bounded exponential backoff, while a wiring fault the policy
names Permanent fails up through the composition
root's race and takes the process down (fail-stop). Each successful poll and each
completed job advances the WorkerHeartbeat, so a stalled loop is visible to the
liveness probe.
Shutdown tears the loop down cleanly: the composition root runs it raced against the server within its resource bracket, so process teardown cancels the loop thread (the combinator never catches cancellation) and an in-flight, un-acked message simply redelivers -- safe, because publishing is idempotent (a version already present is success).
Synopsis
Documentation
workerLoop :: SupervisionPolicy -> WorkerM Void Source #
The continuous consume loop: long-poll for a batch, process it, repeat, supervised under the given policy (the composition root names the wiring faults that must fail up rather than retry; tests inject their own).
A failed poll arrives as the handle's typed QueueFault value:
it is logged and the step backs off and polls again, so a queue outage cannot
kill the worker thread. A successful poll advances the heartbeat (whether or not
the batch was empty), and processBatch advances it again after each completed
job, so a liveness probe sees the loop is alive even while a healthy worker grinds
through a long batch of large artifacts; an idle queue is a healthy empty poll, not
a stall. The heartbeat advances only on demonstrated progress (a successful
receive or a completed job), so a worker that cannot poll at all (a persistently
faulting receive) keeps retrying but never advances it: the heartbeat goes stale
and /livez fails, surfacing a fully-dead worker for the orchestrator to restart.