[−][src]Trait spirit_hyper::ServerBuilder
A trait abstracting the creation of servers.
When spawning a server, there are 3 layers.
- A layer creating the
Server
from the builder. - A layer creating a service for each connection.
- A layer responding to one request.
Each layer must be able to create new instances of the lower layer (by cloning, creating new instances, etc).
This represents the top-level layer. This shall do:
- Create the
Server
. - Call the
with_graceful_shutdown
on it, tying it to the passedshutdown
parameter.
You don't have to implement the trait by hand, a closure with the corresponding signature (see
build
) does the job.
This exists for two reasons:
- To enable different implementations than just closures.
- To allow it to live in
impl Trait
position.
Examples
use std::convert::Infallible; use hyper::{Body, Request, Response}; use hyper::server::Builder; use hyper::service::{make_service_fn, service_fn}; use serde::Deserialize; use spirit::{Empty, Pipeline, Spirit}; use spirit::prelude::*; use spirit_hyper::{BuildServer, HttpServer}; use spirit_tokio::net::limits::Tracked; use tokio::net::TcpStream; use tokio::sync::oneshot::Receiver; const DEFAULT_CONFIG: &str = r#" [server] port = 2235 "#; #[derive(Default, Deserialize)] struct Config { server: HttpServer, } impl Config { fn server(&self) -> HttpServer { self.server.clone() } } async fn request() -> Response<Body> { Response::new(Body::from("Hello world\n")) } type Connection = Tracked<TcpStream>; fn main() { let build_server = |builder: Builder<_>, cfg: &HttpServer, name: &str, shutdown: Receiver<()>| { eprintln!("Creating server {} for {:?}", name, cfg); builder .serve(make_service_fn(|conn: &Connection| { let conn_addr = conn.peer_addr().expect("Peer address doesn't fail"); eprintln!("New connection {}", conn_addr); async { Ok::<_, Infallible>(service_fn(|_req: Request<Body>| async { Ok::<_, Infallible>(request().await) })) } })) .with_graceful_shutdown(async { // Shutting down both by receiving a message and the other end being // dropped. let _ = shutdown.await; }) }; Spirit::<Empty, Config>::new() .config_defaults(DEFAULT_CONFIG) .with( // Let's build a http server as configured by the user Pipeline::new("listen") .extract_cfg(Config::server) // This is where we teach the server what it serves. It is the usual stuff from // hyper. .transform(BuildServer(build_server)) .check() ) .run(|spirit| { Ok(()) }); }
Associated Types
type OutputFut: Future<Output = Result<(), HyperError>> + Send
The future returned by the build.
The future shall represent the graceful shut down server.
Required methods
fn build(
&self,
builder: Builder<Acceptor<Tr::Resource>>,
cfg: &HyperServer<Tr>,
name: &'static str,
shutdown: Receiver<()>
) -> Self::OutputFut
&self,
builder: Builder<Acceptor<Tr::Resource>>,
cfg: &HyperServer<Tr>,
name: &'static str,
shutdown: Receiver<()>
) -> Self::OutputFut
Invokes the build with the parameters.
Directly corresponds to calling the closure for the blank implementation.
Implementors
impl<F, Tr, Fut> ServerBuilder<Tr> for F where
Tr: Fragment,
F: Fn(Builder<Acceptor<Tr::Resource>>, &HyperServer<Tr>, &'static str, Receiver<()>) -> Fut,
Fut: Future<Output = Result<(), HyperError>> + Send,
[src]
Tr: Fragment,
F: Fn(Builder<Acceptor<Tr::Resource>>, &HyperServer<Tr>, &'static str, Receiver<()>) -> Fut,
Fut: Future<Output = Result<(), HyperError>> + Send,