Skip to content

Commit ce18f35

Browse files
committed
docs: improve HttpServer docs on worker / bind relationship wrt factory instantiations
1 parent d3d0208 commit ce18f35

File tree

1 file changed

+45
-8
lines changed

1 file changed

+45
-8
lines changed

actix-web/src/server.rs

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,12 @@ where
9999
B: MessageBody + 'static,
100100
{
101101
/// Create new HTTP server with application factory
102+
///
103+
/// # Worker Count
104+
///
105+
/// The `factory` will be instantiated multiple times in most configurations. See
106+
/// [`bind()`](Self::bind()) docs for more on how worker count and bind address resolution
107+
/// causes multiple server factory instantiations.
102108
pub fn new(factory: F) -> Self {
103109
HttpServer {
104110
factory,
@@ -119,7 +125,18 @@ where
119125

120126
/// Sets number of workers to start (per bind address).
121127
///
122-
/// By default, the number of available physical CPUs is used as the worker count.
128+
/// The default worker count is the determined by [`std::thread::available_parallelism()`]. See
129+
/// its documentation to determine what behavior you should expect when server is run.
130+
///
131+
/// Note that the server factory passed to [`new`](Self::new()) will be instantiated **at least
132+
/// once per worker**. See [`bind()`](Self::bind()) docs for more on how worker count and bind
133+
/// address resolution causes multiple server factory instantiations.
134+
///
135+
/// `num` must be greater than 0.
136+
///
137+
/// # Panics
138+
///
139+
/// Panics if `num` is 0.
123140
pub fn workers(mut self, num: usize) -> Self {
124141
self.builder = self.builder.workers(num);
125142
self
@@ -319,23 +336,41 @@ where
319336
/// Resolves socket address(es) and binds server to created listener(s).
320337
///
321338
/// # Hostname Resolution
322-
/// When `addr` includes a hostname, it is possible for this method to bind to both the IPv4 and
323-
/// IPv6 addresses that result from a DNS lookup. You can test this by passing `localhost:8080`
324-
/// and noting that the server binds to `127.0.0.1:8080` _and_ `[::1]:8080`. To bind additional
325-
/// addresses, call this method multiple times.
339+
///
340+
/// When `addrs` includes a hostname, it is possible for this method to bind to both the IPv4
341+
/// and IPv6 addresses that result from a DNS lookup. You can test this by passing
342+
/// `localhost:8080` and noting that the server binds to `127.0.0.1:8080` _and_ `[::1]:8080`. To
343+
/// bind additional addresses, call this method multiple times.
326344
///
327345
/// Note that, if a DNS lookup is required, resolving hostnames is a blocking operation.
328346
///
347+
/// # Worker Count
348+
///
349+
/// The `factory` will be instantiated multiple times in most scenarios. The number of
350+
/// instantiations is number of [`workers`](Self::workers()) × number of sockets resolved by
351+
/// `addrs`.
352+
///
353+
/// For example, if you've manually set [`workers`](Self::workers()) to 2, and use `127.0.0.1`
354+
/// as the bind `addrs`, then `factory` will be instantiated twice. However, using `localhost`
355+
/// as the bind `addrs` can often resolve to both `127.0.0.1` (IPv4) _and_ `::1` (IPv6), causing
356+
/// the `factory` to be instantiated 4 times (2 workers × 2 bind addresses).
357+
///
358+
/// Using a bind address of `0.0.0.0`, which signals to use all interfaces, may also multiple
359+
/// the number of instantiations in a similar way.
360+
///
329361
/// # Typical Usage
362+
///
330363
/// In general, use `127.0.0.1:<port>` when testing locally and `0.0.0.0:<port>` when deploying
331364
/// (with or without a reverse proxy or load balancer) so that the server is accessible.
332365
///
333366
/// # Errors
367+
///
334368
/// Returns an `io::Error` if:
335369
/// - `addrs` cannot be resolved into one or more socket addresses;
336370
/// - all the resolved socket addresses are already bound.
337371
///
338372
/// # Example
373+
///
339374
/// ```
340375
/// # use actix_web::{App, HttpServer};
341376
/// # fn inner() -> std::io::Result<()> {
@@ -356,6 +391,8 @@ where
356391

357392
/// Resolves socket address(es) and binds server to created listener(s) for plaintext HTTP/1.x
358393
/// or HTTP/2 connections.
394+
///
395+
/// See [`bind()`](Self::bind()) for more details on `addrs` argument.
359396
#[cfg(feature = "http2")]
360397
pub fn bind_auto_h2c<A: net::ToSocketAddrs>(mut self, addrs: A) -> io::Result<Self> {
361398
let sockets = bind_addrs(addrs, self.backlog)?;
@@ -370,7 +407,7 @@ where
370407
/// Resolves socket address(es) and binds server to created listener(s) for TLS connections
371408
/// using Rustls v0.20.
372409
///
373-
/// See [`bind()`](Self::bind) for more details on `addrs` argument.
410+
/// See [`bind()`](Self::bind()) for more details on `addrs` argument.
374411
///
375412
/// ALPN protocols "h2" and "http/1.1" are added to any configured ones.
376413
#[cfg(feature = "rustls-0_20")]
@@ -389,7 +426,7 @@ where
389426
/// Resolves socket address(es) and binds server to created listener(s) for TLS connections
390427
/// using Rustls v0.21.
391428
///
392-
/// See [`bind()`](Self::bind) for more details on `addrs` argument.
429+
/// See [`bind()`](Self::bind()) for more details on `addrs` argument.
393430
///
394431
/// ALPN protocols "h2" and "http/1.1" are added to any configured ones.
395432
#[cfg(feature = "rustls-0_21")]
@@ -408,7 +445,7 @@ where
408445
/// Resolves socket address(es) and binds server to created listener(s) for TLS connections
409446
/// using OpenSSL.
410447
///
411-
/// See [`bind()`](Self::bind) for more details on `addrs` argument.
448+
/// See [`bind()`](Self::bind()) for more details on `addrs` argument.
412449
///
413450
/// ALPN protocols "h2" and "http/1.1" are added to any configured ones.
414451
#[cfg(feature = "openssl")]

0 commit comments

Comments
 (0)