Expand description
Weighted traffic routing for Tower services.
This crate provides a WeightedRouter service that distributes requests
across multiple backend services based on configured weights. It is designed
for canary deployments, progressive rollouts, and controlled traffic splitting.
§Overview
Unlike other tower-resilience patterns which wrap a single service and modify
its behavior, WeightedRouter selects among multiple services. It is a
standalone Service, not a Layer.
All backend services must have the same Request, Response, and Error
types. For canary deployments (same service, different version), this is
the natural case.
§Selection Strategies
-
Deterministic (default): Uses an atomic counter for predictable, repeatable distribution. With weights
[90, 10], every cycle of 100 requests sends exactly 90 to the first backend and 10 to the second. -
Random: Each request independently selects a backend with probability proportional to its weight. Better for high-volume statistical distribution, but may show variance at low traffic.
§Readiness
poll_ready checks that all backends are ready. This is the simplest
and most predictable contract. If a backend is slow or failing, pair it
with a circuit breaker so that readiness resolves quickly (open circuit =
immediate ready or error).
§Example
Because all backends must be the same type S, use BoxService when
constructing from different closures:
use tower::Service;
use tower::util::BoxService;
use tower_resilience_router::WeightedRouter;
let svc_v1: BoxService<String, String, std::io::Error> =
BoxService::new(tower::service_fn(|req: String| async move {
Ok(format!("v1: {}", req))
}));
let svc_v2: BoxService<String, String, std::io::Error> =
BoxService::new(tower::service_fn(|req: String| async move {
Ok(format!("v2: {}", req))
}));
let mut router = WeightedRouter::builder()
.route(svc_v1, 90)
.route(svc_v2, 10)
.build();§Composability
The natural composition pattern puts resilience middleware inside each backend:
use tower::Layer;
use tower_resilience_router::WeightedRouter;
// Each backend gets its own circuit breaker
// let cb = CircuitBreakerLayer::standard().build();
// let router = WeightedRouter::builder()
// .route(cb.layer(svc_v1), 90)
// .route(cb.layer(svc_v2), 10)
// .build();Re-exports§
pub use config::WeightedRouterBuilder;pub use error::WeightedRouterError;pub use events::RouterEvent;pub use selection::SelectionStrategy;
Modules§
- config
- Configuration and builder types for the weighted router. Configuration for the weighted router.
- error
- Error types for routing failures. Error types for the weighted router.
- events
- Event types emitted when requests are routed. Event types for the weighted router.
- selection
- Backend selection strategies (deterministic, random). Selection strategies for weighted routing.
Structs§
- Weighted
Router - A service that routes requests to one of several backends based on weights.