Health checking starts with noticing failures. Today each dispatch records its outcome on the backend as a running streak - consecutive failures or consecutive successes - the raw signal the ejection and recovery logic will read next.
Track consecutive failures and successes on a backend, and have Dispatch record each outcome.
Health checking begins with observation. Before a backend can be ejected for being unhealthy, the balancer has to notice a pattern, and the pattern that matters is a run of outcomes: a single failed request is noise, but several failures in a row is a signal. So each backend keeps two counters - a consecutive-failure streak and a consecutive-success streak - where recording one outcome resets the other. A failure bumps the fail streak and zeroes the success streak, and vice versa.
Wire this into Dispatch so the balancer learns from real traffic: after the
transport returns, record a failure on error and a success otherwise. This is
passive health checking - the health signal is a free byproduct of serving
requests, no separate probe needed. The next chapter turns these raw streaks into
state transitions: eject a backend after enough failures, and later bring it back
after enough successes.
// add failStreak, successStreak int to Backend, with accessorsfunc (b *Backend) RecordFailure() { b.failStreak++; b.successStreak = 0 }func (b *Backend) RecordSuccess() { b.successStreak++; b.failStreak = 0 }// in Dispatch, after the transport returns:// if err != nil { b.RecordFailure() } else { b.RecordSuccess() }