Crates.io | crossbus |
lib.rs | crossbus |
version | 0.0.6-a |
source | src |
created_at | 2023-03-24 13:35:54.20953 |
updated_at | 2023-04-05 15:23:15.694227 |
description | A Platform-Less Runtime-Less Actor Computing Model |
homepage | https://crates.io/crates/crossbus |
repository | https://github.com/hominee/crossbus |
max_upload_size | |
id | 819292 |
size | 2,613,040 |
CrossBus is an implementation of Actor Computing Model, with the concept that
Runtime-less
crossbus neither provide runtime for app execution
nor access the system interface abstraction.
no built-in runtime, but any runtime is allowed,
the system-provided / third-party's / that from
FFI
-binding all work.
Last but not least, even a bare-bone noop-waker executor
can do.
runtime-located features like concurrency
, network
and I/O
are up to implementor.
Bare-Metal Compatible
crossbus links to no system libraries, no libc, and a few upstream libraries enbale you run rust code on bare metal.
the examples folder contains some demos to use crossbus.
Platform-less by Runtime-less
take the advantage of runtime-less, crossbus is able to bypass the limitation of runtime implementor and system interface abstraction and go right straight to manipulate task directly. Only a simple and dummy future executor(look at the no-std example) is sufficed to run crossbus. This is the primary concept of crossbus to run across many platforms or without platforms.
Future-oriented Routine and Events
the futures way to execute task is retained even without runtime thanks to rust. crossbus defines a set of types and traits to allow asynchronous tasks manipulation.
Real-time Execution Control
taking the advantage of the design of future routine, each poll and events alongside can be intercepted for each spawned task during execution, with which more execution control is possible.
Currently crossbus is in its alpha version, all APIs and architecture is not stable yet, and evolves very quickly.
To reduce code redundancy and speed up compilation, crossbus use feature flag to mark the necessary modules/functions, Currently here are some supported Features:
core
/no-std
: the default feature, bare-metal compatiblestd
: rust std library dependentderive
: enable #[derive(Message)]
and #[crossbus::main(...)]
log
: enable logging out states and infos during runtimetime
: enable Actor to known time when blocking/delaying some durationrt
: enable use some common convenient runtimetokio
: convenience to use bare tokio-based runtimeasync-std
: convenience to use async-std-based runtimewasm32
: convenience to use wasm-bindgen-futures-based runtimeunstable
: marker for unstable featuretime-metric
: enabled with unstable
and time
, numerical timing featureforce-poll
: enabled with unstable
, time
-dependent to periodically wakeup future pollingFirst of all, add crossbus
to Cargo.toml
of project
[dependencies]
crossbus = "0.0.6-a"
define Some types and methods according to your business logic.
let's say a actor to add some number up, Okay, then the message should be numbers the actor should know the result after adding.
use crossbus::prelude::*;
struct Num(uisze);
impl Message for Num {}
struct CrossBus {
sum: isize
}
the actor should be created before using it
we tell crossbus how to create it
impl Actor for CrossBus {
type Message = Num;
...
fn create(ctx: &mut Context<Self>) -> Self {
Self { sum: 0, }
}
...
}
Okay, How the actor respond when the message comes? we should tell crossbus.
...
fn action(&mut self, msg: Self::Message, ctx: &mut Context<Self>) {
self.sum += msg.0;
}
...
So far so good, but how to obtain the final result
it can be available when the actor process all messages and stopped, right?
...
fn stopped(&mut self, _: &mut Context<Self>) {
println!("final sum: {}", self.sum);
}
...
Done. Congratulation! You just knew the basic routine to use crossbus. the Full code see below.
Here presents a simple demo to sum numbers.
For more examples, you can go to the examples folder and clone the repo and run them locally.
use crossbus::prelude::*;
struct Num(uisze);
impl Message for Num {}
struct CrossBus {
sum: isize
}
impl Actor for CrossBus {
type Message = Num;
fn create(ctx: &mut Context<Self>) -> Self {
Self { sum: 0, }
}
fn action(&mut self, msg: Self::Message, ctx: &mut Context<Self>) {
self.sum += msg.0;
}
fn stopped(&mut self, _: &mut Context<Self>) {
println!("final sum: {}", self.sum);
assert_eq!(self.sum, 7);
}
}
#[main(runtime = tokio)]
async fn main() {
let (addr, id) = CrossBus::start();
println!("actor {} started", id);
let sender = addr.sender();
sender.send(Num(1)).unwrap();
sender.send(Num(2)).unwrap();
sender.send(Num(4)).unwrap();
}
Feel Free to Contribute! All issues / bugs-report / feature-request / etc are welcome!