tower/balance/p2c/layer.rs
1use super::MakeBalance;
2use std::{fmt, marker::PhantomData};
3use tower_layer::Layer;
4
5/// Construct load balancers ([`Balance`]) over dynamic service sets ([`Discover`]) produced by the
6/// "inner" service in response to requests coming from the "outer" service.
7///
8/// This construction may seem a little odd at first glance. This is not a layer that takes
9/// requests and produces responses in the traditional sense. Instead, it is more like
10/// [`MakeService`] in that it takes service _descriptors_ (see `Target` on [`MakeService`])
11/// and produces _services_. Since [`Balance`] spreads requests across a _set_ of services,
12/// the inner service should produce a [`Discover`], not just a single
13/// [`Service`], given a service descriptor.
14///
15/// See the [module-level documentation](crate::balance) for details on load balancing.
16///
17/// [`Balance`]: crate::balance::p2c::Balance
18/// [`Discover`]: crate::discover::Discover
19/// [`MakeService`]: crate::MakeService
20/// [`Service`]: crate::Service
21pub struct MakeBalanceLayer<D, Req> {
22 _marker: PhantomData<fn(D, Req)>,
23}
24
25impl<D, Req> MakeBalanceLayer<D, Req> {
26 /// Build balancers using operating system entropy.
27 pub fn new() -> Self {
28 Self {
29 _marker: PhantomData,
30 }
31 }
32}
33
34impl<D, Req> Default for MakeBalanceLayer<D, Req> {
35 fn default() -> Self {
36 Self::new()
37 }
38}
39
40impl<D, Req> Clone for MakeBalanceLayer<D, Req> {
41 fn clone(&self) -> Self {
42 Self {
43 _marker: PhantomData,
44 }
45 }
46}
47
48impl<S, Req> Layer<S> for MakeBalanceLayer<S, Req> {
49 type Service = MakeBalance<S, Req>;
50
51 fn layer(&self, make_discover: S) -> Self::Service {
52 MakeBalance::new(make_discover)
53 }
54}
55
56impl<D, Req> fmt::Debug for MakeBalanceLayer<D, Req> {
57 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
58 f.debug_struct("MakeBalanceLayer").finish()
59 }
60}