#actor-model #actor #thread #async #automate

macro interthread

Auto implementation of the Actor Model

28 releases (18 stable)

2.0.1 Jun 3, 2024
1.2.4 Mar 14, 2024
1.2.1 Nov 13, 2023
0.3.0 Jul 12, 2023

#358 in Asynchronous

Download history 269/week @ 2024-03-08 89/week @ 2024-03-15 8/week @ 2024-03-22 87/week @ 2024-03-29 15/week @ 2024-04-05 1/week @ 2024-05-17 81/week @ 2024-05-24 184/week @ 2024-05-31 31/week @ 2024-06-07 7/week @ 2024-06-14

249 downloads per month

MIT/Apache

300KB
6K SLoC

interthread

The actor macro provided by this crate automates the implementation of an Actor Model for a given struct or enum. It handles the intricacies of message routing and synchronization, empowering developers to swiftly prototype the core functionality of their applications. This fast sketching capability is particularly useful when exploring different design options, experimenting with concurrency models, or implementing proof-of-concept systems. Not to mention, the cases where the importance of the program lies in the result of its work rather than its execution.

Examples

Filename: Cargo.toml

[dependencies]
interthread = "2.0.1"
oneshot     = "0.1.6" 

Filename: main.rs


pub struct MyActor {
    value: i8,
}

#[interthread::actor(show)] // <-  this is it 
impl MyActor {
    
    /// This is my comment
    pub fn new( v: i8 ) -> Self {
       Self { value: v } 
    }
    pub fn increment(&mut self) {
        self.value += 1;
    }
    pub fn add_number(&mut self, num: i8) -> i8 {
        self.value += num;
        self.value
    }
    pub fn get_value(&self) -> i8 {
        self.value
    }
}

// try hovering over model parts to see
// generated code as a comment
fn main() {

    let actor = MyActorLive::new(5);

    let mut actor_a = actor.clone();
    let mut actor_b = actor.clone();

    let handle_a = std::thread::spawn( move || { 
    actor_a.increment();
    });

    let handle_b = std::thread::spawn( move || {
    actor_b.add_number(5)
    });

    let _  = handle_a.join();
    let hb = handle_b.join().unwrap();

    // we never know which thread will
    // be first to call the actor so
    // hb = 10 or 11
    assert!(hb >= 10);

    assert_eq!(actor.get_value(), 11);
}

Additionally, the edit option, when combined with the file option, facilitates writing the requested part of the generated code to the file. To substitute the macro with code on file, utilize edit(file) within the macro.

The same example can be run in

with the only difference being that the methods will be marked as async and need to be awaited for asynchronous execution.

Dependencies

~1.7–2.3MB
~48K SLoC