builds / load-balancer / stage-2SHEET 2 / 6 · REV ASIGN IN
ASSEMBLY DIAGRAM — YOUR LOAD BALANCERSCALE: LEARNING
browserthe outside worldFRONT DOOR✓ builtROTOR⚙ buildingPULSE MONITORstage 3SCALESstage 4INSTRUMENT PANELstage 5RELIEF VALVEstage 6
BUILTUNDER CONSTRUCTIONNOT YET IMAGINED INTO EXISTENCE
STAGE 2 · THE ROTOR

The Rotor

One backend is a proxy; several backends is a load balancer.

What you're wiring up

Round-robin is the dumbest fair scheduler there is: 1, 2, 3, 1, 2, 3. You keep a counter, you increment it, you take it modulo the pool size. On paper it's one line of code.

The catch is concurrency. A hundred requests arrive in the same millisecond and all ask the rotor the same question at once: who's next? If two of them read the counter before either writes it back, they get the same answer and your perfect rotation quietly stops being perfect. Nothing crashes. The distribution just goes lopsided in production.

So this stage is really about shared mutable state: one integer, many goroutines, zero races. Do the increment atomically, or put it behind a mutex, and let the race detector be the judge. It names the exact two lines when you get it wrong.

Assembly steps

[ 01 ]
Make --backends accept a comma-separated list and parse it into a pool of backend structs at startup. Reject an empty list loudly.
hint

Validate every URL at boot with url.Parse — dying at startup beats dying once per request.

[ 02 ]
Extract backend selection into a pool type with a Next() *Backend method implementing round-robin.
hint

atomic.AddUint64 then modulo pool size is enough.

hint

A plain int with no lock will pass your manual testing and fail the race detector.

[ 03 ]
Wire Next() into the request path from Stage 1 — every incoming request asks the rotor where to go.
[ 04 ]
Log one line per request: method, path, chosen backend, status, duration.
hint

log.Printf to stderr; keep stdout clean. You will lean on this log in every later stage.

Go deeper (after it passes)

Per-backend counts are your first real load measurement — that habit is DDIA M1 (Measure Before You Build). The counter discipline is Clean Code M10 (Clean Concurrency).