process-fun

Crates.ioprocess-fun
lib.rsprocess-fun
version0.1.1
sourcesrc
created_at2024-12-12 11:38:07.744784
updated_at2024-12-12 16:42:28.588007
descriptionA Rust library for process management and inter-process communication
homepage
repositoryhttps://github.com/eytans/process-fun-rs
max_upload_size
id1481190
size26,837
(eytans)

documentation

https://docs.rs/process-fun

README

process-fun-rs

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

Overview

process-fun-rs provides a simple macro-based approach to execute Rust functions in separate processes. It handles all the complexity of process spawning, argument serialization, and result communication, allowing you to focus on your business logic.

⚠️ Important Notes:

  • This library currently only supports Nix-based systems
  • When passing mutable data to a process function, modifications made within the process will not be reflected in the original data structure in the parent process.

Features

  • Simple #[process] attribute macro for marking functions to create an additional version that runs in separate processes
  • Automatic serialization/deserialization of function return values
  • Type-safe process communication
  • Error handling with custom error types
  • Debug mode for troubleshooting process execution
  • Process timeout support with automatic cleanup

Usage

Add this to your Cargo.toml:

[dependencies]
process-fun = "0.1.0"

Basic example:

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

#[derive(Serialize, Deserialize, Debug)]
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 };
    
    // Execute in a separate process with a timeout
    let mut process = add_points_process(p1, p2).unwrap();
    let result = process.timeout(Duration::from_secs(5)).unwrap();
    assert_eq!(result.x, 4);
    assert_eq!(result.y, 6);
}

Example demonstrating timeout behavior:

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

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

fn main() {
    let mut process = long_running_task_process().unwrap();
    
    // Process will be killed if it doesn't complete within 1 second
    match process.timeout(Duration::from_secs(1)) {
        Ok(result) => println!("Task completed with result: {}", result),
        Err(e) => println!("Task timed out: {}", e)
    }
}

Example demonstrating mutable data behavior:

use process_fun::process;
use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize, Debug)]
struct Counter {
    value: i32,
}

#[process]
pub fn increment_counter(mut counter: Counter) -> Counter {
    counter.value += 1;
    counter
}

fn main() {
    let counter = Counter { value: 0 };
    
    // The counter is passed by value to the process
    let mut process = increment_counter_process(counter).unwrap();
    let result = process.timeout(Duration::from_secs(1)).unwrap();
    
    // Original counter is unchanged
    println!("Original counter value: {}", counter.value);  // Prints: 0
    println!("Result counter value: {}", result.value);     // Prints: 1
}

How It Works

  1. The #[process] attribute macro generates a wrapper function with _process suffix
  2. When called, the wrapper function:
    • Forks the process
    • Returns a ProcessWrapper object
  3. The ProcessWrapper provides timeout functionality:
    • Set a maximum duration for process execution
    • Automatically kills the process if it exceeds the timeout
    • Cleans up resources properly whether the process completes or times out
    • Deserializes the result from the process

Crate Structure

  • process-fun: Main crate providing the public API
  • process-fun-core: Core functionality and types
  • process-fun-macro: Implementation of the #[process] attribute macro

Requirements

  • Nix-based operating system
  • Functions marked with #[process] must:
    • Have arguments and return types that implement Serialize and Deserialize
    • Not take self parameters

License

This project is licensed under the Apache 2 License - see the LICENSE file for details.

Commit count: 24

cargo fmt