diff --git a/docs/server/configuration.md b/docs/server/configuration.md index c93582b2..f40edf2b 100644 --- a/docs/server/configuration.md +++ b/docs/server/configuration.md @@ -1,8 +1,21 @@ # Server configuration -`WireframeServer` provides a builder API for adjusting runtime behaviour. This -guide focuses on tuning the exponential backoff used when accepting connections -fails. +`WireframeServer` provides a builder API for adjusting runtime behaviour. The +server employs a typestate (from `Unbound` to `Bound`) to ensure that binding +occurs before runtime: unbound servers do not expose `run` methods. This guide +focuses on tuning the exponential backoff used when accepting connections fails. + +```rust,no_run +use wireframe::{app::WireframeApp, server::WireframeServer}; + +# #[tokio::main] +# async fn main() -> Result<(), wireframe::server::ServerError> { +let server = WireframeServer::new(|| WireframeApp::default()) + .bind(([127, 0, 0, 1], 0).into())?; +server.run().await?; +# Ok(()) +# } +``` ## Accept loop backoff diff --git a/src/server/config/mod.rs b/src/server/config/mod.rs index cd742850..01e844f5 100644 --- a/src/server/config/mod.rs +++ b/src/server/config/mod.rs @@ -5,8 +5,12 @@ //! TCP binding is provided via the [`binding`](self::binding) module; preamble //! behaviour is customized via the [`preamble`](self::preamble) module. The //! server may be constructed unbound and later bound using -//! [`bind`](WireframeServer::bind) or -//! [`bind_existing_listener`](WireframeServer::bind_existing_listener) on [`Unbound`] servers. +//! [`bind`](super::WireframeServer::bind) or +//! [`bind_existing_listener`](super::WireframeServer::bind_existing_listener) on +//! [`Unbound`](super::Unbound) servers. The `run` methods are available only once +//! the server is [`Bound`](super::Bound), enforcing at compile time that the +//! binding step +//! cannot be skipped. use core::marker::PhantomData; diff --git a/src/server/runtime.rs b/src/server/runtime.rs index 95df19ae..0f469940 100644 --- a/src/server/runtime.rs +++ b/src/server/runtime.rs @@ -74,6 +74,22 @@ where /// # } /// ``` /// + /// Attempting to run a server without binding fails to compile: + /// + /// Binding specifies the network address for the server to listen on. + /// It is required so the server knows where to accept incoming connections. + /// + /// ```compile_fail + /// use wireframe::{app::WireframeApp, server::WireframeServer}; + /// + /// async fn try_run() { + /// WireframeServer::new(|| WireframeApp::default()) + /// .run() + /// .await + /// .expect("unbound servers do not expose run()"); + /// } + /// ``` + /// /// # Errors /// /// Returns a [`ServerError`] if runtime initialisation fails. @@ -113,6 +129,22 @@ where /// # } /// ``` /// + /// Attempting to run a server without binding fails to compile: + /// + /// Binding specifies the network address for the server to listen on. + /// It is required so the server knows where to accept incoming connections. + /// + /// ```compile_fail + /// use wireframe::{app::WireframeApp, server::WireframeServer}; + /// + /// async fn try_run_with_shutdown() { + /// WireframeServer::new(|| WireframeApp::default()) + /// .run_with_shutdown(async {}) + /// .await + /// .expect("unbound servers do not expose run_with_shutdown()"); + /// } + /// ``` + /// /// # Errors /// /// Returns a [`ServerError`] if runtime initialisation fails.