[][src]Crate acteur

Acteur Actor System

An actor system written in Rust that just works. Simple, robust, fast, documented.

Overall features of Acteur

Acteur uses async_std under the hood. This actor system work under the following premises:

  • Simplicity: The API should be small, simple and intuitive
  • Speed: The system should be fast and use all available CPU cores
  • Documented: Everything must be documented with exhaustive examples

Regarding the implementation:

  • Actors have an ID which type is defined by the user for each Actor type
  • Messages are routed to an Actor and an ID
  • Actor life-cycle is automatically handled by the framework
  • Actors are automatically de/allocated depending of their usage
  • Messages for the same Actor & ID are ordered. Everything else is executed concurrently.

State of the implementation

  • DONE - Actor is activated on first message
  • DONE - Actor can send messages to other actors
  • DONE - System can send messages to any actor
  • DONE - Actor self stop
  • DONE - Stop waits for all actors to consume all messages
  • DONE - System statistics
  • DONE - RPC like messages between actors
  • DONE - Services (statefull or stateless, like actors, without ID and processing messages concurrently)
  • DONE - Automatic deallocation of unused actors
  • TODO - ctor deallocation configuration (based in RAM, Actor count or timeout)
  • TODO - Subscribe to message
  • TODO - Fan-out messages
  • TODO - Allow more than 150.000 queued messages per actor (waiting for async_std to have unbounded channels: https://github.com/async-rs/async-std/issues/212)

Example

use acteur::{Actor, Receive, Assistant, Acteur};
use async_trait::async_trait;

#[derive(Debug)]
struct Employee {
    salary: u32
}

#[async_trait]
impl Actor for Employee {
    type Id = u32;

    async fn activate(_: Self::Id) -> Self {
        Employee {
            salary: 0 // Load from DB or set a default,
        }
    }
}

#[derive(Debug)]
struct SalaryChanged(u32);

#[async_trait]
impl Receive<SalaryChanged> for Employee {
    async fn handle(&mut self, message: SalaryChanged, _: &Assistant<Employee>) {
        self.salary = message.0;
    }
}

let sys = Acteur::new();

sys.send_to_actor_sync::<Employee, SalaryChanged>(42, SalaryChanged(55000));

sys.wait_until_stopped();

Structs

Acteur

Acteur is the main inteface to the actor runtime. It allows sending messages, stopping the runtime, set configurations, etc. Once contructed with the method "new" you can start sending messages. The system will automatically start any required actor and unload them when not used.

Assistant

This object is provided to the handle method in Receive and Respond traits for each message that an Actor receives.

ServiceConfiguration
System

This object is provided to the handle method in the Receive trait for each message that an Actor receives. The Actor's assistant allows to send messages and to execute some task over the system.

Enums

ServiceConcurrency

Traits

Actor

The main Trait from this crate.

Notify

This Trait allow Services to receive messages.

Receive

This Trait allow Actors to receive messages.

Respond

This Trait allow Actors to receive messages and, additionally, respond to them.

Serve

This Trait allow Services to receive messages and, additionally, respond to them.

Service

Services are id-less actors that can process messages with certain concurrency. The concurrency level can be configured during the "initialize" method with the ServiceConfiguration struct.