Passive checks only learn from real traffic - so a down backend, getting no traffic, could never recover. Active probing fixes that by running an out-of-band health check against every backend, up or down.
Run one probe round over all backends, recording each result as a success or failure streak.
Active health checking runs a dedicated probe against each backend - a health
endpoint request, a TCP connect - independent of user traffic. It exists to solve a
problem passive checking cannot: a backend marked Down receives no requests, so
without an out-of-band probe it would have no way to prove it has recovered and would
stay ejected forever. That is why the prober iterates All() backends, not just the
Available() ones.
Today the prober only records each probe’s outcome into the same streak counters
your passive checks feed; it deliberately does not yet transition a down backend back
to up. Reusing RecordSuccess and RecordFailure means active and passive signals
accumulate in one place, so a backend recovering under probes and a backend serving
real traffic are treated identically. Keep the probe function injected, exactly like
the transport, so this stays a deterministic offline test rather than a real network
call. Turning a run of successful probes back into Up is the next lesson.
// Pool gains All() returning every backend, up or downtype Probe func(b *Backend) booltype Prober struct { pool *Pool }func (pr *Prober) RunOnce(probe Probe) {for _, b := range pr.pool.All() { // ALL backends, not just Available()if probe(b) { b.RecordSuccess() } else { b.RecordFailure() }}}