ns_router/config.rs
1use std::collections::HashMap;
2use std::fmt::Debug;
3use std::sync::Arc;
4use std::time::Duration;
5
6use abstract_ns::{Name, Address, IpList};
7use abstract_ns::{HostResolve, Resolve, HostSubscribe, Subscribe};
8use internal_traits::{Resolver, Wrapper, NullResolver};
9
10
11/// Configuration of the router
12///
13/// It has a builder interface. You can create a router from `Arc<Config>`
14/// (made by `Config::done`) or a stream of configs.
15#[derive(Clone, Debug)]
16pub struct Config {
17 pub(crate) restart_delay: Duration,
18 pub(crate) convergence_delay: Duration,
19 pub(crate) hosts: HashMap<Name, IpList>,
20 pub(crate) services: HashMap<Name, Address>,
21 pub(crate) suffixes: HashMap<String, Arc<Resolver>>,
22 pub(crate) root: Arc<Resolver>,
23}
24
25impl Config {
26
27 /// Create a new, empty config
28 pub fn new() -> Config {
29 Config {
30 restart_delay: Duration::from_millis(100),
31 convergence_delay: Duration::from_millis(100),
32 hosts: HashMap::new(),
33 services: HashMap::new(),
34 suffixes: HashMap::new(),
35 root: Arc::new(NullResolver),
36 }
37 }
38
39 /// Sets delay after which router will restart any subscription stream
40 ///
41 /// This works both when stream yields end-of-stream and when stream
42 /// has returned error. Default value is 100 milliseconds.
43 pub fn restart_delay(&mut self, delay: Duration) -> &mut Self {
44 self.restart_delay = delay;
45 self
46 }
47
48 /// Sets delay used by [`subscribe_many`] family of functions
49 ///
50 /// The timeout is set when a new set of names arrives via stream or
51 /// when configuration is updated. While the timer is active we don't
52 /// send name updates to the application unless all (new) names are
53 /// resolved.
54 ///
55 /// Good value is bigger than 90 or 99 percentile of name request
56 /// latency, but small enough that delay of this long doesn't introduce
57 /// any hiccups on the application.
58 ///
59 /// For example, if there are names [A, B, C] if C is resolved first
60 /// we wait for the 100 millisecond (by default) timer to finish
61 /// to let A and B also be resolved. If they aren't within the period
62 /// only names in `C` are returned.
63 ///
64 /// Note if names are reloved later, they are added to the address set
65 /// and update is delivered to the client. I.e. it's only important
66 /// something depends on the first address value.
67 ///
68 /// The case where it's important is following: Client establishes
69 /// few persistent connections by picking random IP Addresses from the
70 /// set. Once new addresses arrive connections are still hold until
71 /// one of them is broken. In this case, the first address (or the
72 /// one that can be resolved faster for any reason) would have more
73 /// connections received in most cases which might be a problem.
74 ///
75 /// [`subscribe_many`]: struct.Router.html#tymethod.subscribe_many
76 pub fn convergence_delay(&mut self, delay: Duration) -> &mut Self {
77 self.convergence_delay = delay;
78 self
79 }
80
81 /// Add a host that will be resolved to list of addreses
82 ///
83 /// Hosts added by this host method overrides any other resolvers.
84 pub fn add_host<A>(&mut self, name: &Name, addr: A)
85 -> &mut Self
86 where A: Into<IpList>
87 {
88 self.hosts.insert(name.clone(), addr.into());
89 self
90 }
91
92 /// Add a service that will be resolved to an Address object
93 ///
94 /// Service names added by this host method overrides any other resolvers.
95 pub fn add_service(&mut self, name: &Name, addr: Address) -> &mut Self {
96 self.services.insert(name.clone(), addr);
97 self
98 }
99
100 /// Add a resolver for suffix
101 ///
102 /// Note: you must supply a full resolver here,
103 /// use `null_resolver`/`null_host_resolver` and
104 /// [`interval_subscribe`] or `frozen_subscriber`
105 /// and other combinators to fullfill needed type.
106 ///
107 /// [`interval_subscribe`]: trait.SubscribeExt.html#tymethod.interval_subscribe
108 pub fn add_suffix<S, R>(&mut self, suffix: S, resolver: R)
109 -> &mut Self
110 where S: Into<String>,
111 R: Resolve + HostResolve + Subscribe + HostSubscribe,
112 R: Debug + 'static,
113 {
114 self.suffixes.insert(suffix.into(),
115 Arc::new(Wrapper::new(resolver)));
116 self
117 }
118
119 /// Removes already configured suffix
120 pub fn remove_suffix<S>(&mut self, suffix: &str)
121 -> &mut Self
122 {
123 self.suffixes.remove(suffix);
124 self
125 }
126
127 /// Adds a host resolver used whenever no suffix matches
128 pub fn set_fallthrough<R>(&mut self, resolver: R)
129 -> &mut Self
130 where R: Resolve + HostResolve + Subscribe + HostSubscribe,
131 R: Debug + 'static,
132 {
133 self.root = Arc::new(Wrapper::new(resolver));
134 self
135 }
136
137 /// A convenience method that returns Arc'd config
138 pub fn done(&self) -> Arc<Config> {
139 Arc::new(self.clone())
140 }
141}