tk_listen/lib.rs
1//! A library that allows to listen network sockets with proper resource
2//! limits and error handling.
3//!
4//! Library constists of three things:
5//!
6//! * [`sleep_on_error`][1] -- filters `Stream` of accepted sockets for
7//! errors. Simple errors like `ConnectionReset` are just ignored. Severe
8//! errors like `Too many files open` will delay next `accept()` call for
9//! the delay specified, effectively allowing other connections to be
10//! processed and release resources for new ones.
11//! [Replaces code like this][2].
12//! * [`listen`][3] -- iterates over a stream using [`buffer_unordered`][4]
13//! combinator. It also suppresses errors in futures (because otherwise
14//! every connection error would shut down the whole stream). And returns
15//! `ForEach`-like future, you can `run()` or combine with other futures.
16//! [Stands for code like this][5].
17//! * [`BindMany`] allows to bind to list of addresses and update that list
18//! (i.e. allow configuration reload), resulting into a single stream with
19//! accepted sockets. This a good idea to use it with [abstract-ns] to
20//! resolve list of names to addresses and keep them updated.
21//!
22//! [1]: trait.ListenExt.html#method.sleep_on_error
23//! TODO: Update
24//! [2]: https://git.io/vy9vi#L41-L52
25//! [3]: trait.ListenExt.html#method.listen
26//! [4]: https://docs.rs/futures/0.1.11/futures/stream/trait.Stream.html#method.buffer_unordered
27//! TODO: Update
28//! [5]: https://git.io/vy9vi#L56-L59
29//! [abstract-ns]: https://docs.rs/abstract-ns
30//! [`BindMany`]: struct.BindMany.html
31//!
32//! # Example
33//!
34//! Simple example looks like this:
35//!
36//! ```rust,ignore
37//! let TIME_TO_WAIT_ON_ERROR = Duration::from_millis(100);
38//! let MAX_SIMULTANEOUS_CONNECTIONS = 1000;
39//!
40//! let listener = TcpListener::bind(&addr).unwrap();
41//! lp.run(
42//! listener.incoming()
43//! .sleep_on_error(TIME_TO_WAIT_ON_ERROR)
44//! .map(move |mut socket| {
45//! // Your future is here:
46//! Proto::new(socket)
47//! // Errors should not pass silently
48//! // common idea is to log them
49//! .map(|result| {
50//! match result {
51//! Ok(_) => (),
52//! Err(e) => error!("Conn error: {}", e),
53//! }
54//! })
55//! .map_err(|_| ())
56//! })
57//! .listen(MAX_SIMULTANEOUS_CONNECTIONS)
58//! ).unwrap(); // stream doesn't end in this case
59//! ```
60//!
61//! # Example With Listener Shutdown
62//!
63//! Because tk-listen works as a combinator trait, you can easily add
64//! things, like shutdown:
65//!
66//! ```rust,ignore
67//! let (tx, rx) = oneshot::channel();
68//! lp.run(
69//! listener.incoming()
70//! .sleep_on_error(TIME_TO_WAIT_ON_ERROR)
71//! .map(move |mut socket| {
72//! // Your future is here:
73//! Proto::new(socket)
74//! // Errors should not pass silently
75//! // common Idea is to log them
76//! .map(|result| {
77//! match result {
78//! Ok(_) => (),
79//! Err(e) => error!("Conn error: {}", e),
80//! }
81//! })
82//! .map_err(|_| ())
83//! })
84//! .listen(MAX_SIMULTANEOUS_CONNECTIONS)
85//! .select(|_| rx)
86//! )
87//! ```
88//!
89//! Now listener will be shut down either when `tx` is dropped or when
90//! you send a message via `tx`.
91//!
92//! This is a "force shutdown", meaning it will close all active connections
93//! immediately. It's also possible to stop accepting by closing original
94//! stream (e.g. using `take_while`) and wait until all connections
95//! shutdown gracefully.
96#![warn(missing_docs)]
97
98extern crate futures;
99extern crate tokio;
100
101#[macro_use] extern crate log;
102
103mod bind;
104mod traits;
105mod sleep_on_error;
106mod listen;
107
108pub use traits::ListenExt;
109pub use sleep_on_error::SleepOnError;
110pub use listen::Listen;
111pub use bind::BindMany;