Skip to main content

ntex_server/net/
mod.rs

1//! General-purpose network server.
2//!
3//! Use [`build()`] or [`ServerBuilder`] to register TCP or Unix domain socket
4//! services. Each worker receives its own service instance and processes
5//! connections on a single-threaded runtime.
6use std::sync::atomic::{AtomicUsize, Ordering};
7
8use ntex_util::services::Counter;
9
10mod accept;
11mod builder;
12mod config;
13mod factory;
14mod service;
15mod socket;
16mod test;
17
18pub use crate::{NoConfig, ServerAppConfig};
19
20pub use self::accept::{AcceptLoop, AcceptNotify, AcceptorCommand};
21pub use self::builder::{ServerBuilder, bind_addr, create_tcp_listener};
22pub use self::config::{ServiceConfig, ServiceRuntime};
23pub use self::service::StreamServer;
24pub use self::socket::{Connection, Stream};
25pub use self::test::{TestServer, TestServerBuilder, build_test_server, test_server};
26
27/// Controller for a running network server.
28pub type Server = crate::Server<Connection>;
29
30#[non_exhaustive]
31#[derive(Copy, Clone, Debug, PartialEq, Eq)]
32/// Server readiness status.
33pub enum ServerStatus {
34    /// All workers are ready to accept work.
35    Ready,
36    /// At least one worker is temporarily unavailable.
37    NotReady,
38}
39
40/// Identifier assigned to a registered listener.
41#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
42pub struct Token(usize);
43
44impl Token {
45    #[must_use]
46    #[allow(clippy::should_implement_trait)]
47    /// Returns the current token and advances this value to the next token.
48    pub fn next(&mut self) -> Token {
49        let token = Token(self.0);
50        self.0 += 1;
51        token
52    }
53}
54
55/// Creates a server builder with no application configuration.
56pub fn build() -> ServerBuilder {
57    ServerBuilder::default()
58}
59
60/// Creates a server builder with application configuration.
61pub fn build_with_config<Cfg>(state: Cfg) -> ServerBuilder<Cfg>
62where
63    Cfg: ServerAppConfig,
64{
65    ServerBuilder::new(state)
66}
67
68static MAX_CONNS: AtomicUsize = AtomicUsize::new(25600);
69
70thread_local! {
71    static MAX_CONNS_COUNTER: Counter = Counter::new(MAX_CONNS.load(Ordering::Relaxed));
72}
73
74/// Sets the maximum per-worker number of concurrent connections.
75///
76/// By default, the limit is 25,600 connections per worker.
77pub(super) fn max_concurrent_connections(num: usize) {
78    MAX_CONNS.store(num, Ordering::Relaxed);
79    MAX_CONNS_COUNTER.with(|conns| conns.set_capacity(num));
80}
81
82pub(super) fn num_connections() -> usize {
83    MAX_CONNS_COUNTER.with(Counter::total)
84}
85
86#[cfg(test)]
87mod tests {
88    use super::*;
89
90    #[test]
91    fn token_next() {
92        let mut token = Token(0);
93        assert_eq!(token.next(), Token(0));
94        assert_eq!(token.next(), Token(1));
95        assert_eq!(token, Token(2));
96    }
97}