use std::{net::TcpListener, process}; use axum::{extract::State, routing::get, Router}; use tokio::net::TcpListener as TokioListener; use log::info; use prefork::Prefork; use tower_http::trace::TraceLayer; async fn hello(State((pid, child_num)): State<(u32, u32)>) -> String { format!("Hello from {child_num} with pid {pid}") } async fn child(child_num: u32, listener: TcpListener) { let pid = process::id(); tracing_subscriber::fmt() .with_max_level(tracing::Level::DEBUG) .without_time() .init(); info!("Starting child {child_num}, pid {pid}"); let router = Router::new() .route("/", get(hello)) .layer(TraceLayer::new_for_http()) .with_state((pid, child_num)); let listener = TokioListener::from_std(listener).expect("use tcplistener"); 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("set nonblocking"); let is_parent = Prefork::from_resource(listener) .with_num_processes(10) .with_tokio(child) .fork() .expect("fork"); if is_parent { info!("Parent exit"); } }