Skip to content

Experimenting with a simple actor system in Rust

Notifications You must be signed in to change notification settings

sophiajt/actress

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 

Repository files navigation

actress

A simple actor library in Rust. Still pre-1.0 aka "not really ready for primetime"

Intro

Actress leverages much of what already comes with Rust and is based around the idea that your data and your structures are central.

To this end, Acress supports one trait, called Actor, that represents the minimal requirements on your data types to be used in the actor system. Once you pass a value that meets these requirements into spawn, the system turns your data structure into an actor/active object. After doing so, it hands you the channel end-point that you can communicate with it.

Once an actor is spawned, you can't have any more direct interaction with it. In essence, it becomes isolated (thanks to Rust's type system!), effectively making all communication with it asynchronous.

Another key feature is that communicating with the actors is all-in-one via the message channels. That is, the end-point you get when you spawn an actor serves as a way of also detecting the health of an actor. If an actor has closed its side of the channel, then this will be detectable as you drain the messages.

Usage

Include the actress library

extern crate actress;

Then, implement the Actor trait on your struct

struct SimpleActor {
  state: i32
}

impl actress::Actor for SimpleActor {
  type MessageType = i32;
  fn recv(&mut self, msg: i32) -> bool { self.state = msg; msg == 42 }
}

Finally, spawn and use your new actor

let simple_actor = SimpleActor { state: 1 };
let actor = actress::spawn(simple_actor);
actor.send(10);

Example: two-way echo

extern crate actress;

use std::sync::mpsc::{Sender, SendError, channel};

enum Message { Ping(Sender<Message>), Pong }

struct EchoActor;

impl actress::Actor for EchoActor {
    type MessageType = Message;

    fn recv(&mut self, msg: Self::MessageType) -> bool {
        match msg {
            Message::Ping(c) => { println!("Ping!"); c.send(Message::Pong).unwrap(); true },
            _ => { false }
        }
    }
}

fn act() -> Result<(), SendError<Message>> {
    let echo_actor = EchoActor;

    let (response_tx, response_rx) = channel();

    let actor = actress::spawn(echo_actor);
    try!(actor.send(Message::Ping(response_tx)));

    match response_rx.recv() {
        Ok(Message::Pong) => println!("Pong!"),
        _ => println!("Error receiving response from actor")
    }

    Ok(())
}

fn main() {
    match act() {
        Ok(_) => println!("Message sends complete"),
        _ => println!("Message sends had errors")
    }
}

About

Experimenting with a simple actor system in Rust

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages