2 unstable releases
0.2.0 | Dec 13, 2020 |
---|---|
0.1.0 | Dec 13, 2020 |
#54 in #actor-system
9KB
92 lines
Thespian
Asynchronous actor-based concurrency patterns inspired by Erlang.
License
Licensed under either of
- Apache License, Version 2.0, (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
lib.rs
:
Introduction
Thespian implements a basic actor system in async Rust inspired heavily by Erlang Processes and Supervisors.
Instead of providing a direct messaging interface to the Actor
,
methods defined by the package user on impl Actor<State, Reply>
are used as the external API for the actor. This makes usage of
an Actor
no different than using a reference to a struct.
Internal to the Actor
implementation a mechanism is provided to
run a function inside the Process
holding the Actor
state.
Since all access to the state is handled serially by the Process
,
the behavior of the system resembles a typical Actor
system.
While technically the Process
would be called the actor in typical
usage of the term, for this package the actor's mailbox is instead
called Actor
for better ergonomics. Defining methods on a mailbox
felt odd and confusing.
TODO
- Fix ergonomics around use of newtype pattern for Actor
- Implement supervision tree
Example usage
#[tokio::main]
pub async fn main() {
let (mut process, actor) =
thespian::Process::<State, State>::new_with_state(State::Alpha);
let toggle = Toggle(actor);
let (_process_result, _task_result) = tokio::join! {
async move {
process.start().await;
},
async move {
toggle.flip();
toggle.flip();
println!("get: {:?}", toggle.get().await);
}
};
}
#[derive(Copy, Clone, Debug)]
enum State {
Alpha,
Beta,
}
struct Toggle(thespian::Actor<State, State>);
impl Toggle {
pub async fn get(&self) -> State {
self.0.call_ref_reply(|state, reply| {
reply.send(state.clone());
}).await
}
pub fn flip(&self) {
self.0.call_ref_mut(|state| {
println!("state: {:?}", state);
match state {
State::Alpha => *state = State::Beta,
State::Beta => *state = State::Alpha,
}
});
}
}
Dependencies
~4MB
~60K SLoC