# tractor Actor framework for Rust, modelled after [Pony][Pony]'s actors: * `Actor`s cannot deadlock! * `Send`ing a message to an `Actor` can never fail. * No `async` in `Actor`s. Behaviors cannot block. * `Actor`s are garbage collected. * The implemention of `tractor` is rather simple compared against other Actor implementations in Rust. * It uses `tokio` but was using `async_std` in the past. ## Example In `Cargo.toml` add `tractor = "*"` and `tokio = "1.2.0"`. ```rust use tractor::prelude::*; pub struct Adder { sum: usize, } #[actor(derive_hooks)] impl Adder { fn inc(&mut self) { self.sum += 1; } fn add(&mut self, num: usize) { self.sum += num; } } fn actor_main() { let adder: Addr = Adder { sum: 0 }.start(); /// This sends the `inc` message to the actor. adder.inc(); /// This sends the `add` message to the actor. adder.add(42); } fn main() { ActorSystem::run_to_completion(actor_main); } ``` ## More details * `Actor`s have unbounded mailboxes and `send` is non-blocking. * `Actor`s cannot be manually stopped. They terminate as soon as no further reference to them exists and their mailbox is empty. This implies that sending a message to an `Actor` can never fail except for running out of memory. To avoid overloading of an `Actor` you can check it's current length of it's mailbox. * The behaviors of an `Actor` have no return value! As such, `Actor`s do not support "waiting" for a result. To "simulate" Request/Response, pass the `Actor`s address in the message and respond to it. * The behaviors of an `Actor` are *NOT* `async fn`s! `Async` would imply that the execution can "halt". Use an async actor (`ActorBehaviorAsync` / `ActorHooksAsync`) instead. * NOTE: Any `Actor` cycles will defeat the garbage collection of `Actor`s. [Pony]: https://www.ponylang.io/