abstract_ns/
lib.rs

1//! Abstract traits for name service library
2//!
3//! # Traits
4//!
5//! There are four traits:
6//!
7//! * [`HostResolve`](trait.HostResolve.html)
8//!   -- resolves hostname to a list of IP addresses
9//!   (maps to `A` record in DNS)
10//! * [`Resolve`](trait.Resolve.html)
11//!   -- resolves service name to a set of weighted and prioritized host:port
12//!   pairs ([`Address`](struct.Address.html) struct).
13//!   Maps to `SRV` record in DNS.
14//! * [`HostSubscribe`](trait.HostSubscribe.html)
15//!   -- resolves hostname to a list of IP addresses and tracks changes of
16//!   the addresses
17//! * [`Subscribe`](trait.Subscribe.html)
18//!   -- resolves service name to an [`Address`](struct.Address.html) and
19//!   subscribes on updates of the address
20//!
21//! And there are two address types:
22//!
23//! * [`IpList`](ip_list/struct.IpList.html) -- represents `Arc<Vec<IpAddr>>`
24//! this is used as a result of hostname resolution and it should be converted
25//! into an `Address` struct.
26//! * [`Address`](addr/struct.Address.html) -- represets weighed and
27//! prioritized list of addresses, this is what all user code should accept
28//! for maximum flexibility.
29//!
30//! There are three category of users of the library:
31//!
32//! * Implementors of resolution methods
33//! * Service authors
34//! * Application writers
35//!
36//! Let's explain how to use traits to all of them.
37//!
38//! # Implementing A Resolver
39//!
40//! The `*Resolve` traits are used for ad-hoc resolution of the addresses.
41//!
42//! The `*Subscribe` traits are used to get updates for the name. If your
43//! name service supports updates you should implement it. If not, there
44//! are shims which periodically poll `resolve*` methods to get the
45//! update functionality. Still if you want to poll again based on TTL value
46//! and your resolver does have this value you might want to implement
47//! `*Subscribe` traits too.
48//!
49//! But `abstract-ns` is not just for DNS subsystem. You may want `*.consul`
50//! names to be resolved against consul and subscribe on updates in consul.
51//! Another option is to use eureka, etcd, or zookeeper. All of them having
52//! a way to deliver updates.
53//!
54//! # Writing Protocols
55//!
56//! In general, your library should depend on a minimum set of functionality
57//! here. Here are the rules of thumb:
58//!
59//! 1. Clients: when you need to connect once, accept
60//!    `T: Future<Item=SocketAddr>`, there are adapters that pick a random
61//!    host from `Future<Item=Address>` returned by `PollResolver::resolve`
62//! 2. Clients: when writing a connection pool, accept
63//!    `T: Stream<Item=Address>`, there are adapters to make that stream
64//!    by resolving a single name (into potentially multiple IP addresses),
65//!    a list of names, and a `Stream<Item=Vec<Name>>` (so that config is
66//!    adaptable). As well as adapters that help diffing the `Address`,
67//!    effectively allowing connection pool to adapt
68//!    (also take a look at [tk-pool])
69//! 3. Servers: accept `T: AsyncRead + AsyncWrite`, we have
70//!    [tk-listen] crate that can turn all kinds of configuration
71//!    into actually accepted connections.
72//! 4. Servers: if you need more control accept `TcpStream`
73//!    or `Stream<io::Result<TcpStream>>`, this provides same flexibility
74//!    for name resolution but allows control over parameters of TCP socket
75//!    or of the accepting actual connections
76//!
77//! [tk-pool]: https://crates.io/crates/tk-pool
78//! [tk-listen]: https://crates.io/crates/tk-listen
79//!
80//! # Writing Applications
81//!
82//! Applications should use `ns-router` crate that supports multiple resolvers,
83//! and configuring them on-the-fly.
84//!
85//! # Writing Connection Pools
86//!
87//! As said in [Writing Protocols](#writing-protocols) section a single
88//! connection pool should use `T: Stream<Item=Address>` for as a name
89//! source, this allows good flexibility (also see [tk-pool])
90//!
91//! But in case you need kinda connection pool to a lot of different names
92//! and services, this is the good case for accepting `Resolver` trait itself.
93//! (Still, most of the time actual application should supply
94//!  `ns_router::Router`)
95//!
96#![deny(missing_docs)]
97#![deny(missing_debug_implementations)]
98
99extern crate futures;
100extern crate rand;
101extern crate void;
102#[macro_use] extern crate quick_error;
103
104mod error;
105mod resolver;
106pub mod addr;
107pub mod name;
108pub mod ip_list;
109pub mod combinators;
110
111pub use addr::Address;
112pub use ip_list::IpList;
113pub use error::Error;
114pub use name::Name;
115pub use resolver::{HostResolve, Resolve, HostSubscribe, Subscribe};
116
117trait AssertTraits: Send + Sync {}
118impl AssertTraits for Address {}
119impl AssertTraits for IpList {}
120impl AssertTraits for Name {}
121impl AssertTraits for Error {}