To retire a backend without dropping requests, you drain it - stop sending new work while letting in-flight requests finish. Today you add the Draining state and confirm it leaves selection but keeps its active count until the work completes.
Add a draining state that removes a backend from selection while its in-flight connections finish naturally.
Draining (also called connection draining or graceful shutdown) is how you take a
backend out of service without hurting the requests it is currently handling. Unlike
an abrupt Down, a draining backend keeps its in-flight connections alive to
completion; it simply stops being eligible for new ones. This is what lets you
deploy, scale down, or restart a server cleanly.
The design pays off here: because Available() returns only Up backends and you
modelled status as an enum, adding a third Draining state removes the backend from
selection with no change to any algorithm - it just stops appearing in
Available(). Meanwhile its active count is untouched, so the in-flight leases
continue to tick down as each request finishes and calls its release. The pin to
watch is exactly that split: A vanishes from selection the instant it starts
draining, yet its Active() count stays at 2 and only reaches 0 through normal lease
releases, never by being forcibly reset.
// add Draining to the status enum: const ( Up Status = iota; Down; Draining )func (b *Backend) MarkDraining() { b.status = Draining }func (b *Backend) IsDraining() bool { return b.status == Draining }// IsUp() is still status == Up, so Available() already excludes a draining// backend - no change needed there. Its active count keeps ticking down// as in-flight leases release.