[][src]Crate spirit_tokio

A collection of Fragments and Extensions integrating tokio primitives into spirit.

The crate provides utilities to auto-configure tokio primitives, like listening sockets. This allows, for example, specifying just the function that handles a single connection and let spirit handle all the rest ‒ creating and shutting down the listening socket based on the configuration changes, specifying details like the listen backlog or TCP keepalive, etc. It couples them together and spawns the resulting future onto a tokio runtime (also created by this crate, around the main body of application).

Available fragments

The WithListenLimits is a wrapper that adds limits to number of concurrent connections as well as a backoff timeout in case of soft errors (like „Too many open files“). There are also type aliases TcpListenWithLimits and UnixListenWithLimits.

Runtime

Currently, the crate supports spawning futures on the default runtime only. It also sets up the default runtime as part of the pipelines. However, this works only if at least one pipeline is plugged into the Builder. If all the pipelines you install into spirit are plugged after building, it'll panic.

In such case, the runtime needs to be plugged in manually as part of the setup, like this:

Spirit::<Empty, Empty>::new()
    .with_singleton(Runtime::default())
    .run(|_spirit| {
        // Plugging spirit-tokio pipelines in here into _spirit
        Ok(())
    });

Examples

use std::sync::Arc;

use failure::Error;
use serde::Deserialize;
use spirit::prelude::*;
use spirit_tokio::{HandleListener, TcpListenWithLimits};
use tokio::prelude::*;

const DEFAULT_CONFIG: &str = r#"
[listening_socket]
port = 1234
max-conn = 20
error-sleep = "100ms"
"#;

#[derive(Default, Deserialize)]
struct Config {
    listening_socket: TcpListenWithLimits,
}

impl Config {
    fn listening_socket(&self) -> TcpListenWithLimits {
        self.listening_socket.clone()
    }
}

fn connection<C: AsyncRead + AsyncWrite>(conn: C) -> impl Future<Item = (), Error = Error> {
    tokio::io::write_all(conn, "Hello\n")
        .map(|_| ())
        .map_err(Error::from)
}

fn main() {
    Spirit::<Empty, Config>::new()
        .config_defaults(DEFAULT_CONFIG)
        .with(
            Pipeline::new("listener")
                .extract_cfg(Config::listening_socket)
                .transform(HandleListener(|conn, _cfg: &_| connection(conn)))
        )
        .run(|spirit| {
            Ok(())
        });
}

Further examples are in the git repository.

Re-exports

pub use crate::handlers::HandleListener;
pub use crate::handlers::HandleListenerInit;
pub use crate::handlers::HandleSocket;
pub use crate::net::TcpListen;
pub use crate::net::TcpListenWithLimits;
pub use crate::net::UdpListen;
pub use crate::runtime::Runtime;

Modules

either

Support for alternative choices of configuration.

handlers

Handlers of connections and sockets.

installer

Installer of futures.

net

Autoconfiguration of network primitives of tokio

runtime

An extension to start the tokio runtime at the appropriate time.