Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

One Proxied Request, Fully Traced

1. A connection becomes a typed target

The listener accepts a socket and captures original destination, peer address, transport labels, and drain state. Inbound detection peeks at bytes under a timeout to distinguish TLS, HTTP, and opaque transport. The result enriches a target value used to instantiate the next stack.

2. NewService specializes the stack

Layers do not inspect global configuration on every request. NewService<T> receives a target and constructs a concrete Service<Request> with cloned parameters, policy receivers, metrics labels, caches, and inner services. Param<T> statically declares which configuration a target supplies.

3. HTTP middleware transforms and authorizes

The inbound stack normalizes URIs, attaches tracing/metrics, applies server policy and route policy, classifies responses, and selects local forwarding or gateway/outbound behavior. Each layer wraps the same readiness/call contract.

4. Outbound discovery becomes a service set

Logical destination and route policy select a cached per-target router. Controller or DNS updates feed endpoint add/remove changes. Each endpoint service encapsulates connect, TLS identity, protocol client, timeouts, and metrics.

5. Readiness chooses capacity before ownership transfer

A queue absorbs only configured backlog. The balancer polls endpoint readiness and chooses an available endpoint using load. Service::call then owns the request future. For HTTP/2, many request futures may share one connection; HTTP/1 has different connection concurrency.

6. Completion walks wrappers outward

The endpoint response returns through classification, retry, timeout, tracing, and metrics bodies. End-of-stream matters: a successful response head is not necessarily successful delivery if its body later fails.