1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
//! Support for preforking servers.
//!
//! Preforking is an old fashioned way of multiprocessing, but it is sometimes
//! useful when dealing with systems that run poorly when multi-threaded (e.g.
//! when embedding a Python interpreter).
//!
//! # Features
//!
//! By default, the crate includes tokio as a dependency to launch async servers. If tokio is
//! not needed, include `prefork` as a dependency without default features:
//!
//! ```toml
//! [dependencies]
//! prefork = {version = "...", default-features = false}
//! ```
//! # Example
//!
//! This example opens a socket and then forks multiple processes that accept connections on that socket.
//! To run the example, see `examples/axum.rs` in the code repository:
//!
//! ```sh
//! cargo run --example axum
//! ```
//!
//! Webserver example:
//!
//! ```no_run
//! use std::{net::TcpListener, process};
//!
//! use axum::{extract::State, routing::get, Router};
//!
//! use log::info;
//! use prefork::Prefork;
//!
//! async fn child(child_num: u32, listener: TcpListener) {
//! let pid = process::id();
//! let router = Router::new()
//! .route(
//! "/",
//! get(|State((pid, child_num))| async move {
//! format!("Hello from {child_num} with pid {pid}")
//! }),
//! )
//! .with_state((pid, child_num));
//! let listener = tokio::net::TcpListener::from_std(listener)
//! .expect("bind to port");
//! axum::serve(listener, router).await.expect("start server");
//! }
//!
//! fn main() {
//! let listener = TcpListener::bind("0.0.0.0:3000").expect("bind to port");
//! listener.set_nonblocking(true).expect("nonblocking");
//! let is_parent = Prefork::from_resource(listener)
//! .with_num_processes(10)
//! .with_tokio(child)
//! .fork()
//! .expect("fork");
//! if is_parent {
//! info!("Parent exit");
//! }
//! }
//! ```
pub use crate::;
pub use Pid;