pub struct Server { /* private fields */ }Expand description
An HTTP server to handle incoming connections for Pavex applications. It handles both HTTP1 and HTTP2 connections.
§Example
use std::net::SocketAddr;
use pavex::server::Server;
let addr = SocketAddr::from(([127, 0, 0, 1], 8080));
Server::new()
.bind(addr)
.await?
// Both the routing function and the application state will usually
// be code-generated by Pavex, starting from your `Blueprint`.
// You don't have to define them manually!
.serve(router, application_state)
// The `serve` method returns a `ServerHandle` that you can use to
// interact with the server.
// Calling `.await` on the handle lets you wait until the server
// shuts down.
.await;§Configuration
Server::new returns a new Server with default configuration.
You can customize the server default settings by creating your own ServerConfiguration
and invoking Server::set_config.
§Architecture
By default, Server::serve creates a worker per CPU core and distributes connection from an
acceptor thread using a round-robin strategy.
Each worker has its own single-threaded [tokio] runtime—there is no work stealing across
workers.
Each worker takes care to invoke your routing and request handling logic, with the help
of [hyper].
Implementations§
Source§impl Server
impl Server
Sourcepub fn set_config(self, config: ServerConfiguration) -> Self
pub fn set_config(self, config: ServerConfiguration) -> Self
Configure this Server according to the values set in the ServerConfiguration
passed as input parameter.
It will overwrite any previous configuration set on this Server.
If you want to retrieve the current configuration, use Server::get_config.
Sourcepub fn get_config(&self) -> &ServerConfiguration
pub fn get_config(&self) -> &ServerConfiguration
Get a reference to the ServerConfiguration for this Server.
If you want to overwrite the existing configuration, use Server::set_config.
Sourcepub async fn bind(self, addr: SocketAddr) -> Result<Self>
pub async fn bind(self, addr: SocketAddr) -> Result<Self>
Bind the server to the given address: the server will accept incoming connections from this address when started. Binding an address may fail (e.g. if the address is already in use), therefore this method may return an error.
§Related
Check out Server::listen for an alternative binding mechanism as well as a
discussion of the pros and cons of Server::bind vs Server::listen.
§Note
A Server can be bound to multiple addresses: just call this method multiple times with
all the addresses you want to bind to.
§Example: bind one address
use std::net::SocketAddr;
use pavex::server::Server;
let addr = SocketAddr::from(([127, 0, 0, 1], 8080));
Server::new()
.bind(addr)
.await?
// [...]§Example: bind multiple addresses
use std::net::SocketAddr;
use pavex::server::Server;
let addr1 = SocketAddr::from(([127, 0, 0, 1], 8080));
let addr2 = SocketAddr::from(([127, 0, 0, 1], 4000));
Server::new()
.bind(addr1)
.await?
.bind(addr2)
.await?
// [...]Sourcepub fn listen(self, incoming: IncomingStream) -> Self
pub fn listen(self, incoming: IncomingStream) -> Self
Ask the server to process incoming connections from the provided IncomingStream.
§Server::listen vs Server::bind
Server::bind only requires you to specify the address you want to listen at. The
socket configuration is handled by the Server, with a set of reasonable default
parameters. You have no access to the IncomingStream that gets bound to the address
you specified.
Server::listen, instead, expects an IncomingStream.
You are free to configure the socket as you see please and the Server will just
poll it for incoming connections.
It also allows you to interact with the bound IncomingStream directly
§Example: bind to a random port
use std::net::SocketAddr;
use pavex::server::{IncomingStream, Server};
// `0` is a special port: it tells the OS to assign us
// a random **unused** port
let addr = SocketAddr::from(([127, 0, 0, 1], 0));
let incoming = IncomingStream::bind(addr).await?;
// We can then retrieve the actual port we were assigned
// by the OS.
let addr = incoming.local_addr()?.to_owned();
Server::new()
.listen(incoming);
// [...]§Example: set a custom socket backlog
use std::net::SocketAddr;
use socket2::Domain;
use pavex::server::{IncomingStream, Server};
// `0` is a special port: it tells the OS to assign us
// a random **unused** port
let addr = SocketAddr::from(([127, 0, 0, 1], 0));
let socket = socket2::Socket::new(
Domain::for_address(addr),
socket2::Type::STREAM,
Some(socket2::Protocol::TCP),
)
.expect("Failed to create a socket");
socket.set_reuse_address(true)?;
socket.set_nonblocking(true)?;
socket.bind(&addr.into())?;
// The custom backlog!
socket.listen(2048_i32)?;
let listener = std::net::TcpListener::from(socket);
Server::new()
.listen(listener.try_into()?)
// [...]§Note
A Server can listen to multiple streams of incoming connections: just call this method
multiple times!
Sourcepub fn serve<HandlerFuture, ApplicationState>(
self,
handler: fn(Request<Incoming>, Option<ConnectionInfo>, ApplicationState) -> HandlerFuture,
application_state: ApplicationState,
) -> ServerHandle
pub fn serve<HandlerFuture, ApplicationState>( self, handler: fn(Request<Incoming>, Option<ConnectionInfo>, ApplicationState) -> HandlerFuture, application_state: ApplicationState, ) -> ServerHandle
Start listening for incoming connections.
You must specify:
- a handler function, which will be called for each incoming request;
- the application state, the set of singleton components that will be available to your handler function.
Both the handler function and the application state are usually code-generated by Pavex
starting from your Blueprint.
§Wait for the server to shut down
serve returns a ServerHandle.
Calling .await on the handle lets you wait until the server shuts down.
§Panics
This method will panic if the Server has no registered sources of incoming connections,
i.e. if you did not call Server::bind or Server::listen before calling serve.
If you’d rather handle the error, use Server::try_serve instead.
Sourcepub fn try_serve<HandlerFuture, ApplicationState>(
self,
handler: fn(Request<Incoming>, Option<ConnectionInfo>, ApplicationState) -> HandlerFuture,
application_state: ApplicationState,
) -> Result<ServerHandle, Error>
pub fn try_serve<HandlerFuture, ApplicationState>( self, handler: fn(Request<Incoming>, Option<ConnectionInfo>, ApplicationState) -> HandlerFuture, application_state: ApplicationState, ) -> Result<ServerHandle, Error>
A fallible version of Server::serve.
It will return an error, rather than panicking, if the Server has no registered sources
of incoming connections, i.e. if you did not call Server::bind or Server::listen
before calling serve.
Trait Implementations§
Auto Trait Implementations§
impl Freeze for Server
impl RefUnwindSafe for Server
impl Send for Server
impl Sync for Server
impl Unpin for Server
impl UnwindSafe for Server
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
§impl<T> Paint for Twhere
T: ?Sized,
impl<T> Paint for Twhere
T: ?Sized,
§fn fg(&self, value: Color) -> Painted<&T>
fn fg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the foreground set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like red() and
green(), which have the same functionality but are
pithier.
§Example
Set foreground color to white using fg():
use yansi::{Paint, Color};
painted.fg(Color::White);Set foreground color to white using white().
use yansi::Paint;
painted.white();§fn bright_black(&self) -> Painted<&T>
fn bright_black(&self) -> Painted<&T>
§fn bright_red(&self) -> Painted<&T>
fn bright_red(&self) -> Painted<&T>
§fn bright_green(&self) -> Painted<&T>
fn bright_green(&self) -> Painted<&T>
§fn bright_yellow(&self) -> Painted<&T>
fn bright_yellow(&self) -> Painted<&T>
§fn bright_blue(&self) -> Painted<&T>
fn bright_blue(&self) -> Painted<&T>
§fn bright_magenta(&self) -> Painted<&T>
fn bright_magenta(&self) -> Painted<&T>
§fn bright_cyan(&self) -> Painted<&T>
fn bright_cyan(&self) -> Painted<&T>
§fn bright_white(&self) -> Painted<&T>
fn bright_white(&self) -> Painted<&T>
§fn bg(&self, value: Color) -> Painted<&T>
fn bg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the background set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like on_red() and
on_green(), which have the same functionality but
are pithier.
§Example
Set background color to red using fg():
use yansi::{Paint, Color};
painted.bg(Color::Red);Set background color to red using on_red().
use yansi::Paint;
painted.on_red();§fn on_primary(&self) -> Painted<&T>
fn on_primary(&self) -> Painted<&T>
§fn on_magenta(&self) -> Painted<&T>
fn on_magenta(&self) -> Painted<&T>
§fn on_bright_black(&self) -> Painted<&T>
fn on_bright_black(&self) -> Painted<&T>
§fn on_bright_red(&self) -> Painted<&T>
fn on_bright_red(&self) -> Painted<&T>
§fn on_bright_green(&self) -> Painted<&T>
fn on_bright_green(&self) -> Painted<&T>
§fn on_bright_yellow(&self) -> Painted<&T>
fn on_bright_yellow(&self) -> Painted<&T>
§fn on_bright_blue(&self) -> Painted<&T>
fn on_bright_blue(&self) -> Painted<&T>
§fn on_bright_magenta(&self) -> Painted<&T>
fn on_bright_magenta(&self) -> Painted<&T>
§fn on_bright_cyan(&self) -> Painted<&T>
fn on_bright_cyan(&self) -> Painted<&T>
§fn on_bright_white(&self) -> Painted<&T>
fn on_bright_white(&self) -> Painted<&T>
§fn attr(&self, value: Attribute) -> Painted<&T>
fn attr(&self, value: Attribute) -> Painted<&T>
Enables the styling [Attribute] value.
This method should be used rarely. Instead, prefer to use
attribute-specific builder methods like bold() and
underline(), which have the same functionality
but are pithier.
§Example
Make text bold using attr():
use yansi::{Paint, Attribute};
painted.attr(Attribute::Bold);Make text bold using using bold().
use yansi::Paint;
painted.bold();§fn rapid_blink(&self) -> Painted<&T>
fn rapid_blink(&self) -> Painted<&T>
§fn quirk(&self, value: Quirk) -> Painted<&T>
fn quirk(&self, value: Quirk) -> Painted<&T>
Enables the yansi [Quirk] value.
This method should be used rarely. Instead, prefer to use quirk-specific
builder methods like mask() and
wrap(), which have the same functionality but are
pithier.
§Example
Enable wrapping using .quirk():
use yansi::{Paint, Quirk};
painted.quirk(Quirk::Wrap);Enable wrapping using wrap().
use yansi::Paint;
painted.wrap();§fn clear(&self) -> Painted<&T>
👎Deprecated since 1.0.1: renamed to resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.
fn clear(&self) -> Painted<&T>
resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.§fn whenever(&self, value: Condition) -> Painted<&T>
fn whenever(&self, value: Condition) -> Painted<&T>
Conditionally enable styling based on whether the [Condition] value
applies. Replaces any previous condition.
See the crate level docs for more details.
§Example
Enable styling painted only when both stdout and stderr are TTYs:
use yansi::{Paint, Condition};
painted.red().on_yellow().whenever(Condition::STDOUTERR_ARE_TTY);