compio-actor 0.1.0

Actors for Compio
Documentation
use std::{convert::Infallible, io};

use compio_actor::{
    Actor, ActorExit, Call, Cluster, Handler, Mailbox,
    process_group::{ProcessGroup, Strategy},
};

struct Worker;

#[derive(Debug)]
struct Add;
#[derive(Debug)]
struct Read;

impl Actor for Worker {
    type Arguments = ();
    type Error = Infallible;
    type State = usize;

    async fn pre_start(
        &self,
        _myself: &Mailbox<Self>,
        (): Self::Arguments,
    ) -> Result<Self::State, Self::Error> {
        Ok(0)
    }
}

impl Handler<Add> for Worker {
    async fn handle(
        &self,
        _myself: &Mailbox<Self>,
        Add: Add,
        state: &mut Self::State,
    ) -> Result<(), Self::Error> {
        *state += 1;
        Ok(())
    }
}

impl Handler<Call<Read, usize>> for Worker {
    async fn handle(
        &self,
        _myself: &Mailbox<Self>,
        call: Call<Read, usize>,
        state: &mut Self::State,
    ) -> Result<(), Self::Error> {
        call.reply(*state).ok();
        Ok(())
    }
}

#[compio_macros::main]
async fn main() -> io::Result<()> {
    let cluster = Cluster::new()?;
    let (first, first_handle) = cluster.spawn(|| Worker, ()).await.unwrap();
    let (second, second_handle) = cluster.spawn(|| Worker, ()).await.unwrap();

    let workers = ProcessGroup::with_strategy(Strategy::RoundRobin);
    let _first = workers.join(first.broker());
    let _second = workers.join(second.broker());
    for _ in 0..4 {
        workers.send(Add).unwrap();
    }

    let readers = ProcessGroup::new();
    let _first = readers.join(first.broker::<Call<Read, usize>>());
    let _second = readers.join(second.broker::<Call<Read, usize>>());
    assert_eq!(readers.call(Read).await.unwrap(), 2);
    assert_eq!(readers.call(Read).await.unwrap(), 2);

    first.stop();
    second.stop();
    assert_eq!(first_handle.await.unwrap(), ActorExit::Stopped);
    assert_eq!(second_handle.await.unwrap(), ActorExit::Stopped);
    cluster.join().await
}