Expand description
§Tokiactor
§About Tokiactor
tokiactor is a minimized implementation of actor pattern based on tokio runtime. No concepts like or System or Context involved, just MessageHandle and Actor.
In tokiactor, Actor is a wrapped function, sync ort async.
syncfunction will be executed in multiple system threadsasyncfunction will be executed intokiogreen thread asynchronously.
Large batch tasks like processing thousands of pictures can be done in parallel by leveraging buffered futures::StreamExt trait from crate futures.
§Installation
Add tokiactor to Cargo.toml
[dependencies]
tokiactor = "*"tokiactor needs tokio to make things work.
§Getting start
Following code will create Adder actor, then, actor spawned in Handle, Adder will be called thru Handle::handle method asynchronously.
use tokio;
use tokiactor::*;
let rt = tokio::runtime::Runtime::new().unwrap().block_on(
async move {
// create handle, then spawn a closure.
let handle = Handle::new(1).spawn(move |i: i32| i+ 41);
// call actor thru 'handle' method
assert_eq!(handle.handle(1).await, 42);
}
);or, we can create Actor from async Closure:
use tokio;
use tokiactor::*;
let rt = tokio::runtime::Runtime::new().unwrap().block_on(
async move {
let handle = Handle::new(1).spawn_tokio(move |i: i32| async move {i + 41});
assert_eq!(handle.handle(1).await, 42);
}
);or, create Actor from blocking fn, then run Actor in parallel
use tokio;
use tokiactor::*;
use futures::StreamExt;
fn adder_fn(i: i32) -> i32 {
std::thread::sleep(std::time::Duration::from_secs(1));
i+ 41
}
let rt = tokio::runtime::Runtime::new().unwrap().block_on(
async move {
let handle = Handle::new(10).spawn_n(10, adder_fn);
let results = futures::stream::iter((0..10))
.map(|i| handle.handle(i))
.buffered(10)
.collect::<Vec<_>>().await;
assert_eq!(results[9], 50)
}
);§Actor spawn
There are different ways to spawn an Actor:
-
To spawn sync
Actor-
Handle::spawn: spawnActorin1background thread -
Handle::spawn_n: spawnnActorinfnimplCloneinnbackground threads.
-
-
To spawn async
ActorHandle::spawn_tokio: spawnActorin background tokio thread, every asynchandlewill spawn an new tokio thread at background.
please check docs.rs for further infomation.
§Handle
Handle can be connected together, build another type of Handle
use tokio;
use tokiactor::*;
let rt = tokio::runtime::Runtime::new().unwrap().block_on(
async move {
let add = Handle::new(1).spawn(move |i: i32| i + 1);
let sub = Handle::new(1).spawn(move |i: i32| i - 1);
let div = Handle::new(1).spawn(move |i: i32| {
match i == 0 {
false => Some(10/i),
true => None
}
});
let mul = Handle::new(1).spawn(move |i: i32| i * 10);
let handle = add.then(sub).then(div).map(mul);
assert_eq!(handle.handle(0).await, None);
assert_eq!(handle.handle(2).await, Some(50));
}
);Handle can spawn both async and sync actor at the same time
use tokio;
use tokiactor::*;
let rt = tokio::runtime::Runtime::new().unwrap().block_on(
async move {
// Just a demo, don't do it in real code.
// spawn a fn
let handle = Handle::new(1).spawn(move |i: i32| i + 1);
// spawn an async fn
handle.spawn_tokio(move |i: i32| async move {i * 2});
}
);Please check examples/icecream.rs out for more complicated use case.
Structs§
- Actor
- Actor to wrap function
- Chain
Error - Chain error together when connecto two
ResultHandletogether - Handle
- Channel to communicated with
Actorinstances
Enums§
- Handle
Error - Error container for channel communication
Traits§
- Inspector
- A trait for inspecting input and output values.
Type Aliases§
- Option
Handle - Handle return value is an
Option - Result
Handle - Handle return value is a
Result