vin/
lib.rs

1//! # vin
2//! A lightweight, ergonomic and unconventional actor crate.
3//! 
4//! ## Overview
5//! 
6//! Vin's goal is to be an ergonomic, unconventional actor library. Vin doesn't follow the conventional implementations for actor libraries, but tries to be as simple as possible, while still providing an ergonomic and rich interface by integrating itself with [`tokio`] as much as possible. Each actor gets its own task to poll messages and execute handlers on. Its address is shared by a simple `Arc`. Vin also provides a way to gracefully shutdown all actors without having to do the manual labour yourself. Actor data is stored in its actor context and is retrievable for reading with `Actor::ctx()` and for writing with `Actor::ctx_mut()` which acquire a `RwLock` to the data. Vin also provides a "task actor" which is simply a [`tokio`] task spun up and synchronized with Vin's shutdown system.
7//! 
8//! Vin completely relies on [`tokio`](https://github.com/tokio-rs/tokio) (for the async runtime), [`log`](https://github.com/rust-lang/log) (for diagnostics) and [`async_trait`](https://github.com/dtolnay/async-trait).
9//! 
10//! ## Examples
11//! 
12//! ### Regular actors
13//! Basic usage of [`vin`].
14//! 
15//! ```rust
16//! use vin::prelude::*;
17//! use std::time::Duration;
18//! use tracing::Level;
19//! 
20//! #[vin::message]
21//! #[derive(Debug, Clone)]
22//! pub enum Msg {
23//!     Foo,
24//!     Bar,
25//!     Baz,
26//! }
27//! 
28//! #[vin::message(result = u32, error = String)]
29//! struct MsgWithResult(bool);
30//! 
31//! #[vin::actor]
32//! #[vin::handles(Msg)]
33//! #[vin::handles(MsgWithResult)]
34//! struct MyActor {
35//!     pub number: u32,
36//! }
37//! 
38//! #[async_trait]
39//! impl vin::Hooks for MyActor {}
40//! 
41//! #[async_trait]
42//! impl vin::Handler<Msg> for MyActor {
43//!     async fn handle(&self, msg: Msg) -> Result<(), ()> {
44//!         let ctx = self.ctx().await;
45//!         println!("The message is: {:?} and the number is {}", msg, ctx.number);
46//! 
47//!         Ok(())
48//!     }
49//! }
50//! 
51//! #[async_trait]
52//! impl vin::Handler<MsgWithResult> for MyActor {
53//!     async fn handle(&self, MsgWithResult(should_err): MsgWithResult) -> Result<u32, String> {
54//! 		if should_err { Err("error".to_string()) }
55//!         else { Ok(42) }
56//!     }
57//! }
58//! 
59//! #[tokio::main]
60//! async fn main() {
61//!     tracing_subscriber::fmt()
62//!         .with_max_level(Level::TRACE)
63//!         .init();
64//! 
65//!     let ctx = VinContextMyActor { number: 42 };
66//!     let actor = MyActor::start("test", ctx).unwrap();
67//!     actor.send(Msg::Bar).await;
68//!     tokio::time::sleep(Duration::from_millis(500)).await;
69//! 	let res = actor.send_and_wait(MsgWithResult(false)).await.unwrap();
70//! 	assert_eq!(res, 42);
71//!     vin::shutdown();
72//!     vin::wait_for_shutdowns().await;
73//! }
74//! ```
75//! 
76//! ### Task actors
77//! Basic usage of task actors in [`vin`].
78//! 
79//! ```rust
80//! use vin::*;
81//! use std::time::Duration;
82//! use tracing::Level;
83//! 
84//! #[vin::task]
85//! #[derive(Debug, Clone, PartialEq, Eq)]
86//! struct MyTaskActor {
87//!     pub number: u32,
88//! }
89
90//! #[async_trait]
91//! impl vin::Task for MyTaskActor {
92//!     async fn task(&self, ctx: Self::Context) -> anyhow::Result<()> {
93//!         for i in 0..ctx.number {
94//!             log::info!("{}. iteration", i);
95//!         }
96//! 
97//!         Ok(())
98//!     }
99//! }
100//! 
101//! #[tokio::main]
102//! async fn main() {
103//!     tracing_subscriber::fmt()
104//!         .with_max_level(Level::TRACE)
105//!         .init();
106//! 
107//! 	let ctx = VinContextMyTaskActor { number: 5 };
108//!     let actor = MyTaskActor::start("test_task", ctx);
109//!     tokio::time::sleep(Duration::from_millis(100)).await;
110//! 	actor.close();
111//!     vin::shutdown();
112//!     vin::wait_for_shutdowns().await;
113//! }
114//! ```
115
116pub use vin_core::{
117	self, State, Message, Addr, Actor, ActorId, Handler, Forwarder,
118	StrongAddr, WeakAddr, StrongErasedAddr, WeakErasedAddr,
119	shutdown, shutdown_future, add_actor, remove_actor,
120	wait_for_shutdowns, ActorQueryError, ActorStartError, query_actor, query_actor_erased,
121	send, send_and_wait, Hooks, TaskActor, Task, TaskAddr,
122};
123pub use vin_macros::{actor, handles, task, message};
124
125#[doc(hidden)] pub use ::vin_core::anyhow;
126#[doc(hidden)] pub use ::vin_core::async_channel;
127#[doc(hidden)] pub use ::vin_core::async_trait::{self, async_trait};
128#[doc(hidden)] pub use ::vin_core::crossbeam;
129#[doc(hidden)] pub use ::vin_core::downcast_rs;
130#[doc(hidden)] pub use ::vin_core::futures;
131#[doc(hidden)] pub use ::vin_core::tokio;
132#[doc(hidden)] pub use ::vin_core::log;
133
134#[doc(hidden)]
135pub mod prelude {
136	pub use crate::{Addr, Actor, Forwarder, StrongAddr, WeakAddr, StrongErasedAddr, WeakErasedAddr, TaskActor, TaskAddr};
137	
138	pub use crate::anyhow;
139	pub use crate::async_channel;
140	pub use crate::async_trait::{self, async_trait};
141	pub use crate::crossbeam;
142	pub use crate::downcast_rs;
143	pub use crate::futures;
144	pub use crate::tokio;
145	pub use crate::log;
146}