Crate prefork

source ·
Expand description

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:

[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:

cargo run --example axum

Webserver example:

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");
    }
}

Structs§

  • Process identifier
  • Build a server that starts by forking processes.
  • A Prefork Server. A server is used to fork() child processes.

Enums§

  • Possible errors that can occur when attempting to fork.

Constants§

Functions§

Type Aliases§

  • The result of attempting to fork.