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

Build a Smaller Linkerd2-proxy

Build a target-specialized Tower proxy with dynamic endpoint discovery, bounded readiness, balancing, replay-safe retries, and graceful drain.

1. Proxy one concrete HTTP service

Accept TCP, serve HTTP, rewrite the destination, and forward with Hyper. Record connection and request ownership before adding generic layers.

2. Define NewService<T> and target parameters

Create Target { logical, original_dst, labels }, a service factory, and Param<P>. Construct a service once per target instead of consulting global maps in every call.

3. Build middleware layers

Implement timeout, request counting, response classification, and authorization as Tower services/layers. Keep their errors concrete until an outer response mapping boundary.

4. Add discovery and a cached router

Use a watch/change channel to add and remove endpoints. Cache one router per logical destination and evict it after idle time. Preserve its endpoint state across requests.

5. Implement readiness and bounded pressure

Give endpoints capacity flags, poll only ready endpoints, and place a bounded queue with a failfast deadline before the balancer. Demonstrate queue, reject, and recovery under a paused endpoint.

6. Balance by load

Choose two ready endpoints randomly and send to the lower observed load. Hold a load guard until response body completion/drop, not merely response headers.

7. Add safe retries

Buffer request bodies up to a cap, classify retryable responses, enforce a token budget and overall deadline, and prove a non-replayable streaming body is never retried.

8. Add TLS and live credentials

Distribute Arc<ClientConfig> through a watch channel. New connections use the latest config while established connections retain the config that negotiated them.

9. Drain

Broadcast shutdown, stop accepts, reject new routing work, and wait for active bodies/connections under a deadline. Test a stream that finishes and one that never does.

10. Compare with production

Map to inbound/outbound stacks, NewService, Param, Tower Service, queues, failfast, idle caches, routers, endpoint discovery, P2C pools, retry replay, classifiers, mTLS, metrics, and drain. The real proxy adds mesh protocols, policies, opaque TCP, gateways, tap, observability, and extensive control-plane recovery. Preserve its center: capacity-aware typed services whose dynamic state follows the target hierarchy.