Reverse Proxy / Load Balancer (Rust)
Topics: round-robin, health checks, atomics, Service
Problem
Distribute requests across backend servers using round-robin, skipping unhealthy backends.
Backends are Services (Request -> Response), so the balancer routes to them in-process — the same
hand-written HTTP shape as the other networking challenges, no real sockets.
pub struct Backend { pub url: String, /* health + service */ }
pub struct LoadBalancer { /* … */ }
impl LoadBalancer {
pub fn new(backends: Vec<Backend>) -> Self;
pub fn next(&self) -> Result<&Backend, NoHealthyBackends>;
pub fn set_healthy(&self, url: &str, healthy: bool);
pub fn health_check(&self, cancel: &Cancel, interval: Duration, path: &str);
}
impl Service for LoadBalancer { /* proxy to next(), or 502 */ }
next returns the next healthy backend in round-robin order; Err(NoHealthyBackends) if none.
Try each backend at most once so an all-down pool can't loop forever.
LoadBalancer::call proxies the request to next()'s backend, or responds 502 if none are
healthy.
set_healthy flips a backend's health by url.
health_check probes each backend (GET path) immediately and then every interval until
cancel fires, marking healthy iff the probe returns 200.
You implement next and the Service::call routing; set_healthy, check_once, and the
health_check loop are provided.
Key concepts
- Atomics: an
AtomicU64 counter for round-robin and an AtomicBool per backend for health —
no locks on the hot path.
- Round-robin with skip: advance
counter % len, but loop at most len times so an
all-unhealthy pool returns the error instead of spinning.
- Health-check loop: probe on an interval, cancellable via the token — the same shape as a real
gateway's background health checker.
Grading
Your solution.rs is compiled together with a trusted tests.rs (which include!s it) using
rustc --test. Only solution.rs is yours to edit.
Sign in to submit your solution.