Crate process_fun

Source
Expand description

§process-fun

A library for easily running Rust functions in separate processes with minimal boilerplate.

§Overview

This crate provides a simple macro-based approach to execute Rust functions in separate processes. The #[process] attribute macro creates an additional version of your function that runs in a separate process, while keeping the original function unchanged. This allows you to choose between in-process and out-of-process execution as needed.

§Process Execution Model

When a function marked with #[process] is called through its _process variant:

  1. A new process is forked from the current process
  2. A ProcessWrapper is returned which allows:
    • Waiting for completion with optional timeout
    • Automatic process cleanup on timeout or drop
    • Safe result deserialization

This execution model ensures complete isolation between the parent and child processes, making it suitable for running potentially risky or resource-intensive operations.

§Usage

use process_fun::process;
use serde::{Serialize, Deserialize};
use std::time::Duration;

#[derive(Serialize, Deserialize, Debug, Clone)]
struct Point {
    x: i32,
    y: i32,
}

#[process]
pub fn add_points(p1: Point, p2: Point) -> Point {
    Point {
        x: p1.x + p2.x,
        y: p1.y + p2.y,
    }
}

fn main() {
    let p1 = Point { x: 1, y: 2 };
    let p2 = Point { x: 3, y: 4 };
     
    // Use original function (in-process)
    let result1 = add_points(p1.clone(), p2.clone());
     
    // Use process version with timeout (out-of-process)
    let mut process = add_points_process(p1, p2).unwrap();
    let result2 = process.timeout(Duration::from_secs(5)).unwrap();
     
    assert_eq!(result1.x, result2.x);
    assert_eq!(result1.y, result2.y);
}

§Timeout Example

use process_fun::process;
use std::time::Duration;
use std::thread;

#[process]
fn long_task() -> i32 {
    thread::sleep(Duration::from_secs(10));
    42
}

fn main() {
    let mut process = long_task_process().unwrap();
     
    // Process will be killed if it exceeds timeout
    match process.timeout(Duration::from_secs(1)) {
        Ok(result) => println!("Task completed: {}", result),
        Err(e) => println!("Task timed out: {}", e)
    }
}

Modules§

ser
sys

Structs§

ProcessWrapper
Wrapper for a process execution that allows awaiting or aborting the process

Enums§

ProcessFunError
Errors that can occur during process-fun operations

Functions§

create_pipes
Create a pipe for communication between parent and child processes
fork_process
Fork the current process and return ForkResult
read_from_pipe
Read data from a pipe
read_start_time_from_pipe
Read start time from pipe
stat_pid_start
write_time
Write time to pipe
write_to_pipe
Write data to a pipe and close it

Type Aliases§

FunId
Type alias for function identifiers, represented as filesystem paths

Attribute Macros§

process
Attribute macro that creates an additional version of a function that executes in a separate process.