A load balancer spreads work across a set of backends, so the first thing to model is one backend - an address it forwards to and whether it is currently up. Today you build that type and toggle its health.
Create a backend with an id and address that starts up, and can be marked down and up again.
Every load balancer sits in front of a group of backends - the real servers that do the work. A backend is mostly an address to forward a request to, plus a little state the balancer keeps about it. The most important piece of that state is whether the backend is healthy right now, because a balancer must never send new work to a server it believes is down.
Model the health as a small status value rather than a bare boolean. Today it
only needs Up and Down, but later in the project a backend can also be
Draining (finishing its in-flight work while taking no new requests), and an
enum leaves room for that third state without a rewrite. Start every backend Up;
the health-check chapter is where status starts changing on its own.
// status is an enum so DRAINING can join UP and DOWN latertype Status intconst ( Up Status = iota; Down )type Backend struct {ID, Addr stringstatus Status}func NewBackend(id, addr string) *Backend { return &Backend{ID: id, Addr: addr, status: Up} }func (b *Backend) IsUp() bool { return b.status == Up }func (b *Backend) MarkDown() { b.status = Down }func (b *Backend) MarkUp() { b.status = Up }