1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
//! A full-featured router for abstract-ns
//!
//! A router should be an entry point for your application. It solves two
//! purposes:
//!
//! 1. Allow to use different name resolution mechanisms without cluttering
//! your app with too much generics
//! 2. Optimize performance: we connect to resolvers via channels, so polling
//! an `ResolveFuture` or `AddrStream` is cheap.
//!
//! # Example
//!
//! A simple resolver you should start with:
//!
//! ```rust
//! # use std::time::Duration;
//! # extern crate tokio_core;
//! extern crate abstract_ns;
//! extern crate ns_router;
//! extern crate ns_std_threaded;
//! use abstract_ns::HostResolve;
//! use ns_router::SubscribeExt;
//!
//! # fn main() {
//! # let core = tokio_core::reactor::Core::new().unwrap();
//! let ns = ns_router::Router::from_config(&ns_router::Config::new()
//! .set_fallthrough(ns_std_threaded::ThreadedResolver::new()
//! .null_service_resolver()
//! .interval_subscriber(Duration::new(1, 0), &core.handle()))
//! .done(),
//! &core.handle());
//! # }
//!
//! ```
//!
//! This is a bit verbose, but this means:
//!
//! 1. Use stdlib resolver
//! 2. Do not resolve SRV (stdlib resolver can't do that)
//! 3. Poll for a new address every second (for subscriptions)
//!
//! # Names in Configs
//!
//! You should use [`resolve_auto`] and [`subscribe_many`] for resolving
//! names that come from configuration files. In it's simplest form it
//! accepts a string:
//!
//! ```rust,ignore
//! ns.resolve_auto("localhost:8080")
//! ns.resolve_auto("_xmpp-server._tcp.gmail.com") // if resolver has SRV
//! ```
//!
//! But you may force specific mode:
//! ```rust.ignore
//! use ns_router::AutoName::*;
//! ns.resolve_auto(Service("localhost")); // resolve bare `localhost` as SRV
//! ```
//!
//! All the same forms work for `subscribe_many` and `subscribe_many_stream`
//!
//! # Updating Names
//!
//! If you're writing server you might need to react on name changes.
//! `abstract-ns` gives you a way to `subscribe` for the name.
//!
//! Router gives you a little bit more:
//!
//! 1. You can create router with [`from_stream`] or [`updating_config`] and
//! push configuration updates to router.
//! 2. The [`subscribe_many_stream`] method allows to subsribe to a stream of
//! names: i.e. every time your user changes list of names to be used for
//! some service, new names are resolved and applied immediately.
//!
//! Both kinds of updates are delivered to the application as a next update
//! in a stream without any additional code on receiver side.
//!
//! [`resolve_auto`]: struct.Router.html#method.resolve_auto
//! [`subscribe_many`]: struct.Router.html#method.subscribe_many
//! [`subscribe_many_stream`]: struct.Router.html#method.subscribe_many_stream
//! [`from_stream`]: struct.Router.html#method.from_stream
//! [`updating_config`]: struct.Router.html#method.updating_config
//!
//! # Configuring Router
//!
//! To show you an example how router can be configured:
//!
//! ```rust,ignore
//! let cfg = &Config::new()
//! // resolution of hosts from memory for performance or tests
//! .add_host(&"localhost".parse().unwrap(),
//! vec!["127.0.0.1".parse().unwrap()])
//! // resolve `.consul` names via consul DNS SRV or HTTP
//! .add_suffix("consul", consul_resolver)
//! // use stdlib for other things
//! .set_fallthrough(std_resolver)
//! .done();
//!
//! ```
//!
extern crate abstract_ns;
extern crate async_slot;
extern crate futures;
extern crate tokio_core;
extern crate void;
extern crate log;
extern crate quick_error;
pub use Router;
pub use Config;
pub use ;
pub use SubscribeExt;