wip, allow to run tokio based futures in the bastion executor (#299)

* wip, allow to run tokio based futures in the bastion executor

* use tokio::main!

* runtime handles

* wip, adding tests and making them compatible with runtime-tokio

* ok docs remaining, no clue how to handle it

* wip, doctests

* wip: getting there...

* tests are finally passing!

* runtime-tokio => tokio-runtime

* tokio_test is amazing <3

* woopsie

* prepare for master, so we can beta test the tokio feature
This commit is contained in:
Jeremy Lempereur 2021-02-01 19:49:54 +01:00 committed by GitHub
parent 86644839ed
commit 39ff2b8a89
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
35 changed files with 1853 additions and 150 deletions

View File

@ -26,11 +26,12 @@ maintenance = { status = "actively-developed" }
[features]
unstable = []
tokio-runtime = ["tokio"]
[dependencies]
lightproc = "0.3.5"
# lightproc = "0.3.5"
bastion-utils = "0.3.2"
# lightproc = { path = "../lightproc" }
lightproc = { path = "../lightproc" }
# bastion-utils = { path = "../bastion-utils" }
crossbeam-utils = "0.8"
@ -49,10 +50,15 @@ lever = "0.1"
tracing = "0.1.19"
crossbeam-queue = "0.3.0"
# Feature tokio
tokio = {version = "1.1", features = ["rt", "rt-multi-thread"], optional = true }
[target.'cfg(target_os = "windows")'.dependencies]
winapi = { version = "^0.3.8", features = ["basetsd"] }
[dev-dependencies]
tokio = {version = "1.1", features = ["rt", "rt-multi-thread", "macros"] }
tokio-test = "0.4.0"
proptest = "^0.10"
futures = "0.3.5"
tracing-subscriber = "0.2.11"

View File

@ -8,9 +8,36 @@ use std::thread;
use std::time::Duration;
use test::Bencher;
#[cfg(feature = "tokio-runtime")]
mod tokio_benchs {
use super::*;
#[bench]
fn blocking(b: &mut Bencher) {
tokio_test::block_on(async { _blocking(b) });
}
#[bench]
fn blocking_single(b: &mut Bencher) {
tokio_test::block_on(async {
_blocking_single(b);
});
}
}
#[cfg(not(feature = "tokio-runtime"))]
mod no_tokio_benchs {
use super::*;
#[bench]
fn blocking(b: &mut Bencher) {
_blocking(b);
}
#[bench]
fn blocking_single(b: &mut Bencher) {
_blocking_single(b);
}
}
// Benchmark for a 10K burst task spawn
#[bench]
fn blocking(b: &mut Bencher) {
fn _blocking(b: &mut Bencher) {
b.iter(|| {
(0..10_000)
.map(|_| {
@ -27,8 +54,7 @@ fn blocking(b: &mut Bencher) {
}
// Benchmark for a single blocking task spawn
#[bench]
fn blocking_single(b: &mut Bencher) {
fn _blocking_single(b: &mut Bencher) {
b.iter(|| {
blocking::spawn_blocking(
async {

View File

@ -10,11 +10,38 @@ use std::thread;
use std::time::Duration;
use test::Bencher;
#[cfg(feature = "tokio-runtime")]
mod tokio_benchs {
use super::*;
#[bench]
fn blocking(b: &mut Bencher) {
tokio_test::block_on(async { _blocking(b) });
}
#[bench]
fn blocking_single(b: &mut Bencher) {
tokio_test::block_on(async {
_blocking_single(b);
});
}
}
#[cfg(not(feature = "tokio-runtime"))]
mod no_tokio_benchs {
use super::*;
#[bench]
fn blocking(b: &mut Bencher) {
_blocking(b);
}
#[bench]
fn blocking_single(b: &mut Bencher) {
_blocking_single(b);
}
}
// Benchmark for a 10K burst task spawn
#[bench]
fn run_blocking(b: &mut Bencher) {
fn _blocking(b: &mut Bencher) {
b.iter(|| {
let handles = (0..10_000)
(0..10_000)
.map(|_| {
blocking::spawn_blocking(
async {
@ -24,24 +51,18 @@ fn run_blocking(b: &mut Bencher) {
ProcStack::default(),
)
})
.collect::<Vec<_>>();
run(join_all(handles), ProcStack::default())
.collect::<Vec<_>>()
});
}
// Benchmark for a single blocking task spawn
#[bench]
fn run_blocking_single(b: &mut Bencher) {
fn _blocking_single(b: &mut Bencher) {
b.iter(|| {
run(
blocking::spawn_blocking(
async {
let duration = Duration::from_millis(1);
thread::sleep(duration);
},
ProcStack::default(),
),
blocking::spawn_blocking(
async {
let duration = Duration::from_millis(1);
thread::sleep(duration);
},
ProcStack::default(),
)
});

View File

@ -9,9 +9,36 @@ use lightproc::proc_stack::ProcStack;
use std::time::Duration;
use test::Bencher;
#[cfg(feature = "tokio-runtime")]
mod tokio_benchs {
use super::*;
#[bench]
fn spawn_lot(b: &mut Bencher) {
tokio_test::block_on(async { _spawn_lot(b) });
}
#[bench]
fn spawn_single(b: &mut Bencher) {
tokio_test::block_on(async {
_spawn_single(b);
});
}
}
#[cfg(not(feature = "tokio-runtime"))]
mod no_tokio_benchs {
use super::*;
#[bench]
fn spawn_lot(b: &mut Bencher) {
_spawn_lot(b);
}
#[bench]
fn spawn_single(b: &mut Bencher) {
_spawn_single(b);
}
}
// Benchmark for a 10K burst task spawn
#[bench]
fn spawn_lot(b: &mut Bencher) {
fn _spawn_lot(b: &mut Bencher) {
let proc_stack = ProcStack::default();
b.iter(|| {
let _ = (0..10_000)
@ -29,8 +56,7 @@ fn spawn_lot(b: &mut Bencher) {
}
// Benchmark for a single task spawn
#[bench]
fn spawn_single(b: &mut Bencher) {
fn _spawn_single(b: &mut Bencher) {
let proc_stack = ProcStack::default();
b.iter(|| {
spawn(

View File

@ -37,14 +37,20 @@ where
handle
}
struct BlockingRunner {}
struct BlockingRunner {
// We keep a handle to the tokio runtime here to make sure
// it will never be dropped while the DynamicPoolManager is alive,
// In case we need to spin up some threads.
#[cfg(feature = "tokio-runtime")]
runtime_handle: tokio::runtime::Handle,
}
impl DynamicRunner for BlockingRunner {
fn run_static(&self, park_timeout: Duration) -> ! {
loop {
while let Ok(task) = POOL.receiver.recv_timeout(THREAD_RECV_TIMEOUT) {
trace!("static thread: running task");
task.run();
self.run(task);
}
trace!("static: empty queue, parking with timeout");
@ -55,7 +61,7 @@ impl DynamicRunner for BlockingRunner {
loop {
while let Ok(task) = POOL.receiver.recv_timeout(THREAD_RECV_TIMEOUT) {
trace!("dynamic thread: running task");
task.run();
self.run(task);
}
trace!(
"dynamic thread: parking - {:?}",
@ -66,11 +72,25 @@ impl DynamicRunner for BlockingRunner {
}
fn run_standalone(&self) {
while let Ok(task) = POOL.receiver.recv_timeout(THREAD_RECV_TIMEOUT) {
task.run();
self.run(task);
}
trace!("standalone thread: quitting.");
}
}
impl BlockingRunner {
fn run(&self, task: LightProc) {
#[cfg(feature = "tokio-runtime")]
{
self.runtime_handle.spawn_blocking(|| task.run());
}
#[cfg(not(feature = "tokio-runtime"))]
{
task.run();
}
}
}
/// Pool interface between the scheduler and thread pool
struct Pool {
sender: Sender<LightProc>,
@ -80,11 +100,28 @@ struct Pool {
static DYNAMIC_POOL_MANAGER: OnceCell<DynamicPoolManager> = OnceCell::new();
static POOL: Lazy<Pool> = Lazy::new(|| {
let runner = Arc::new(BlockingRunner {});
#[cfg(feature = "tokio-runtime")]
{
let runner = Arc::new(BlockingRunner {
// We use current() here instead of try_current()
// because we want bastion to crash as soon as possible
// if there is no available runtime.
runtime_handle: tokio::runtime::Handle::current(),
});
DYNAMIC_POOL_MANAGER
.set(DynamicPoolManager::new(*low_watermark() as usize, runner))
.expect("couldn't create dynamic pool manager");
}
#[cfg(not(feature = "tokio-runtime"))]
{
let runner = Arc::new(BlockingRunner {});
DYNAMIC_POOL_MANAGER
.set(DynamicPoolManager::new(*low_watermark() as usize, runner))
.expect("couldn't create dynamic pool manager");
}
DYNAMIC_POOL_MANAGER
.set(DynamicPoolManager::new(*low_watermark() as usize, runner))
.expect("couldn't create dynamic pool manager");
DYNAMIC_POOL_MANAGER
.get()
.expect("couldn't get static pool manager")

View File

@ -27,6 +27,18 @@ use tracing::trace;
/// use bastion_executor::prelude::*;
/// use lightproc::prelude::*;
///
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # start();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # start();
/// # }
/// #
/// # fn start() {
/// let pid = 1;
/// let stack = ProcStack::default().with_pid(pid);
///
@ -43,6 +55,7 @@ use tracing::trace;
/// },
/// stack.clone(),
/// );
/// # }
/// ```
pub fn spawn<F, T>(future: F, stack: ProcStack) -> RecoverableHandle<T>
where
@ -134,14 +147,20 @@ pub struct Pool {
receiver: Receiver<LightProc>,
}
struct AsyncRunner {}
struct AsyncRunner {
// We keep a handle to the tokio runtime here to make sure
// it will never be dropped while the DynamicPoolManager is alive,
// In case we need to spin up some threads.
#[cfg(feature = "tokio-runtime")]
runtime_handle: tokio::runtime::Handle,
}
impl DynamicRunner for AsyncRunner {
fn run_static(&self, park_timeout: Duration) -> ! {
loop {
for task in &POOL.receiver {
trace!("static: running task");
task.run();
self.run(task);
}
trace!("static: empty queue, parking with timeout");
@ -152,7 +171,7 @@ impl DynamicRunner for AsyncRunner {
loop {
while let Ok(task) = POOL.receiver.try_recv() {
trace!("dynamic thread: running task");
task.run();
self.run(task);
}
trace!(
"dynamic thread: parking - {:?}",
@ -163,20 +182,50 @@ impl DynamicRunner for AsyncRunner {
}
fn run_standalone(&self) {
while let Ok(task) = POOL.receiver.try_recv() {
task.run();
self.run(task);
}
trace!("standalone thread: quitting.");
}
}
impl AsyncRunner {
fn run(&self, task: LightProc) {
#[cfg(feature = "tokio-runtime")]
{
self.runtime_handle.spawn_blocking(|| task.run());
}
#[cfg(not(feature = "tokio-runtime"))]
{
task.run();
}
}
}
static DYNAMIC_POOL_MANAGER: OnceCell<DynamicPoolManager> = OnceCell::new();
static POOL: Lazy<Pool> = Lazy::new(|| {
let runner = Arc::new(AsyncRunner {});
#[cfg(feature = "tokio-runtime")]
{
let runner = Arc::new(AsyncRunner {
// We use current() here instead of try_current()
// because we want bastion to crash as soon as possible
// if there is no available runtime.
runtime_handle: tokio::runtime::Handle::current(),
});
DYNAMIC_POOL_MANAGER
.set(DynamicPoolManager::new(*low_watermark() as usize, runner))
.expect("couldn't create dynamic pool manager");
}
#[cfg(not(feature = "tokio-runtime"))]
{
let runner = Arc::new(AsyncRunner {});
DYNAMIC_POOL_MANAGER
.set(DynamicPoolManager::new(*low_watermark() as usize, runner))
.expect("couldn't create dynamic pool manager");
}
DYNAMIC_POOL_MANAGER
.set(DynamicPoolManager::new(*low_watermark() as usize, runner))
.expect("couldn't create dynamic pool manager");
DYNAMIC_POOL_MANAGER
.get()
.expect("couldn't get static pool manager")

View File

@ -7,11 +7,11 @@ use crossbeam_utils::sync::Parker;
use lightproc::proc_stack::ProcStack;
use std::cell::{Cell, UnsafeCell};
use std::future::Future;
use std::mem;
use std::mem::ManuallyDrop;
use std::pin::Pin;
use std::sync::Arc;
use std::task::{Context, Poll, RawWaker, RawWakerVTable, Waker};
use std::mem;
///
/// This method blocks the current thread until passed future is resolved with an output (including the panic).

View File

@ -216,8 +216,7 @@ impl DynamicPoolManager {
.name("bastion-driver-dynamic".to_string())
.spawn(move || {
Self::affinity_pinner();
let parker = || self.park_thread();
clone.run_dynamic(&parker);
clone.run_dynamic(&|| self.park_thread());
})
.expect("cannot start dynamic thread");
});

View File

@ -8,8 +8,19 @@ mod tests {
dbg!(core_ids);
}
#[test]
fn pool_check() {
pool::get();
#[cfg(feature = "tokio-runtime")]
mod tokio_tests {
#[tokio::test]
async fn pool_check() {
super::pool::get();
}
}
#[cfg(not(feature = "tokio-runtime"))]
mod no_tokio_tests {
#[test]
fn pool_check() {
super::pool::get();
}
}
}

View File

@ -4,8 +4,23 @@ use lightproc::proc_stack::ProcStack;
use std::thread;
use std::time::Duration;
#[test]
fn test_run_blocking() {
#[cfg(feature = "tokio-runtime")]
mod tokio_tests {
#[tokio::test]
async fn test_run_blocking() {
super::run_test()
}
}
#[cfg(not(feature = "tokio-runtime"))]
mod no_tokio_tests {
#[test]
fn test_run_blocking() {
super::run_test()
}
}
fn run_test() {
let output = run(
blocking::spawn_blocking(
async {

View File

@ -43,14 +43,14 @@ distributed = [
]
scaling = []
docs = ["distributed", "scaling", "default"]
tokio-runtime = ["bastion-executor/tokio-runtime"]
[package.metadata.docs.rs]
features = ["docs"]
rustdoc-args = ["--cfg", "feature=\"docs\""]
[dependencies]
bastion-executor = "0.4"
bastion-executor = { git = "https://github.com/bastion-rs/bastion.git" }
lightproc = "0.3.5"
# bastion-executor = { version = "= 0.3.7-alpha.0", path = "../bastion-executor" }
# lightproc = { version = "= 0.3.6-alpha.0", path = "../lightproc" }
@ -75,6 +75,7 @@ tracing-subscriber = "0.2.6"
tracing = "0.1.15"
anyhow = "1.0.31"
crossbeam-queue = "0.3.0"
log = "0.4.14"
[target.'cfg(not(windows))'.dependencies]
nuclei = "0.1"
@ -88,3 +89,8 @@ bastion-utils = { version = "0.3.2", path = "../bastion-utils" }
rand = "0.7.3"
rayon = "1.3.1"
num_cpus = "1.13.0"
# hello_tokio example
tokio = { version="1.1", features = ["time", "macros"] }
bastion-executor = { git = "https://github.com/bastion-rs/bastion.git" }
once_cell = "1.5.2"
tokio-test = "0.4.0"

View File

@ -0,0 +1,101 @@
use anyhow::Result as AnyResult;
use bastion::prelude::*;
#[cfg(feature = "tokio-runtime")]
use tokio;
use tracing::{error, warn, Level};
/// `cargo run --features=tokio-runtime --example hello_tokio`
///
/// We are focusing on the contents of the msg! macro here.
/// If you would like to understand how the rest works,
/// Have a look at the `hello_world.rs` example instead :)
///
/// Log output:
///
/// Jan 31 14:55:55.677 WARN hello_tokio: just spawned!
/// Jan 31 14:55:56.678 WARN hello_tokio: Ok let's handle a message now.
/// Jan 31 14:55:56.678 ERROR hello_tokio: just received hello, world!
/// Jan 31 14:55:56.678 WARN hello_tokio: sleeping for 2 seconds without using the bastion executor
/// Jan 31 14:55:58.680 WARN hello_tokio: and done!
/// Jan 31 14:55:58.681 WARN hello_tokio: let's sleep for 5 seconds within a blocking block
/// Jan 31 14:56:03.682 WARN hello_tokio: awaited 5 seconds
/// Jan 31 14:56:03.682 ERROR hello_tokio: waited for the blocking! to be complete!
/// Jan 31 14:56:03.682 ERROR hello_tokio: not waiting for spawn! to be complete, moving on!
/// Jan 31 14:56:03.683 WARN hello_tokio: let's sleep for 10 seconds within a spawn block
/// Jan 31 14:56:13.683 WARN hello_tokio: the spawn! is complete
/// Jan 31 14:56:15.679 WARN hello_tokio: we're done, stopping the bastion!
#[cfg(feature = "tokio-runtime")]
#[tokio::main]
async fn main() -> AnyResult<()> {
// Initialize tracing logger
// so we get nice output on the console.
let subscriber = tracing_subscriber::fmt()
.with_max_level(Level::WARN)
.finish();
tracing::subscriber::set_global_default(subscriber).unwrap();
Bastion::init();
Bastion::start();
let workers = Bastion::children(|children| {
children.with_exec(|ctx: BastionContext| {
async move {
warn!("just spawned!");
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
warn!("Ok let's handle a message now.");
msg! {
ctx.recv().await?,
msg: &'static str => {
// Printing the incoming msg
error!("just received {}", msg);
warn!("sleeping for 2 seconds without using the bastion executor");
tokio::time::sleep(std::time::Duration::from_secs(2)).await;
warn!("and done!");
// let's wait until a tokio powered future is complete
run!(blocking! {
warn!("let's sleep for 5 seconds within a blocking block");
tokio::time::sleep(std::time::Duration::from_secs(5)).await;
warn!("awaited 5 seconds");
});
error!("waited for the blocking! to be complete!");
// let's spawn a tokio powered future and move on
spawn! {
warn!("let's sleep for 10 seconds within a spawn block");
tokio::time::sleep(std::time::Duration::from_secs(10)).await;
warn!("the spawn! is complete");
};
error!("not waiting for spawn! to be complete, moving on!");
};
_: _ => ();
}
Ok(())
}
})
})
.expect("Couldn't create the children group.");
let asker = async {
workers.elems()[0]
.tell_anonymously("hello, world!")
.expect("Couldn't send the message.");
};
run!(asker);
// Let's wait until the blocking! and the spawn! are complete on the child side.
run!(blocking!({
std::thread::sleep(std::time::Duration::from_secs(20))
}));
warn!("we're done, asking bastion to stop!");
// We are done, stopping the bastion!
Bastion::stop();
warn!("bastion stopped!");
Ok(())
}
#[cfg(not(feature = "tokio-runtime"))]
fn main() {
panic!("this example requires the tokio-runtime feature: `cargo run --features=tokio-runtime --example hello_tokio`")
}

View File

@ -21,7 +21,6 @@ async fn run(addr: impl ToSocketAddrs) -> io::Result<()> {
// Spawn a task that echoes messages from the client back to it.
spawn(echo(stream));
}
Ok(())
}
#[cfg(target_os = "windows")]

View File

@ -29,7 +29,18 @@ distributed_api! {
/// ```rust
/// use bastion::prelude::*;
///
/// fn main() {
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// fn run() {
/// /// Creating the system's configuration...
/// let config = Config::new().hide_backtraces();
/// // ...and initializing the system with it (this is required)...
@ -172,6 +183,18 @@ impl Bastion {
/// # Example
///
/// ```rust
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// use bastion::prelude::*;
///
/// Bastion::init();
@ -181,6 +204,7 @@ impl Bastion {
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
///
/// [`Config`]: struct.Config.html
@ -206,6 +230,18 @@ impl Bastion {
/// ```rust
/// use bastion::prelude::*;
///
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// let config = Config::new()
/// .show_backtraces();
///
@ -216,6 +252,7 @@ impl Bastion {
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
///
/// [`Config`]: struct.Config.html
@ -248,6 +285,18 @@ impl Bastion {
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// let sp_ref: SupervisorRef = Bastion::supervisor(|sp| {
@ -259,6 +308,7 @@ impl Bastion {
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
///
/// [`Supervisor`]: supervisor/struct.Supervisor.html
@ -307,6 +357,18 @@ impl Bastion {
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// let children_ref: ChildrenRef = Bastion::children(|children| {
@ -328,6 +390,7 @@ impl Bastion {
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
///
/// [`Children`]: children/struct.Children.html
@ -357,6 +420,18 @@ impl Bastion {
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// let children_ref: ChildrenRef = Bastion::spawn(|ctx: BastionContext| {
@ -369,6 +444,7 @@ impl Bastion {
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
///
/// [`Children::with_exec`]: children/struct.Children.html#method.with_exec
@ -410,7 +486,18 @@ impl Bastion {
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// let msg = "A message containing data.";
@ -437,7 +524,7 @@ impl Bastion {
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// # }
/// ```
pub fn broadcast<M: Message>(msg: M) -> Result<(), M> {
debug!("Bastion: Broadcasting message: {:?}", msg);
@ -459,6 +546,18 @@ impl Bastion {
/// ```rust
/// use bastion::prelude::*;
///
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// Bastion::init();
///
/// // Use bastion, spawn children and supervisors...
@ -470,6 +569,7 @@ impl Bastion {
/// #
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
pub fn start() {
debug!("Bastion: Starting.");
@ -488,6 +588,19 @@ impl Bastion {
/// ```rust
/// use bastion::prelude::*;
///
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
///
/// Bastion::init();
///
/// // Use bastion, spawn children and supervisors...
@ -499,6 +612,7 @@ impl Bastion {
///
/// Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
pub fn stop() {
debug!("Bastion: Stopping.");
@ -517,6 +631,18 @@ impl Bastion {
/// ```rust
/// use bastion::prelude::*;
///
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// Bastion::init();
///
/// // Use bastion, spawn children and supervisors...
@ -527,6 +653,7 @@ impl Bastion {
///
/// Bastion::kill();
/// # Bastion::block_until_stopped();
/// # }
/// ```
pub fn kill() {
debug!("Bastion: Killing.");
@ -553,6 +680,18 @@ impl Bastion {
/// # Example
///
/// ```rust
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// use bastion::prelude::*;
///
/// Bastion::init();
@ -567,6 +706,7 @@ impl Bastion {
/// Bastion::block_until_stopped();
/// // The system is now stopped. A child might have
/// // stopped or killed it...
/// # }
/// ```
///
/// [`Bastion::stop()`]: #method.stop

View File

@ -19,6 +19,18 @@ pub(crate) enum CallbackType {
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// Bastion::children(|children| {
@ -41,6 +53,7 @@ pub(crate) enum CallbackType {
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
///
/// [`Supervisor`]: supervisor/struct.Supervisor.html
@ -61,6 +74,18 @@ impl Callbacks {
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// Bastion::children(|children| {
@ -83,6 +108,7 @@ impl Callbacks {
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
///
/// [`Supervisor::with_callbacks`]: supervisor/struct.Supervisor.html#method.with_callbacks
@ -107,6 +133,18 @@ impl Callbacks {
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// # Bastion::supervisor(|supervisor| {
@ -138,6 +176,7 @@ impl Callbacks {
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
///
/// [`Supervisor`]: supervisor/struct.Supervisor.html
@ -166,6 +205,18 @@ impl Callbacks {
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// # Bastion::supervisor(|supervisor| {
@ -199,6 +250,7 @@ impl Callbacks {
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
///
/// [`Supervisor`]: supervisor/struct.Supervisor.html
@ -227,6 +279,18 @@ impl Callbacks {
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// # Bastion::supervisor(|supervisor| {
@ -260,6 +324,7 @@ impl Callbacks {
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
///
/// [`Supervisor`]: supervisor/struct.Supervisor.html
@ -292,6 +357,18 @@ impl Callbacks {
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// # Bastion::supervisor(|supervisor| {
@ -323,6 +400,7 @@ impl Callbacks {
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
///
/// [`Supervisor`]: supervisor/struct.Supervisor.html

View File

@ -67,6 +67,18 @@ impl ChildRef {
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// Bastion::children(|children| {
@ -82,6 +94,7 @@ impl ChildRef {
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
pub fn id(&self) -> &BastionId {
&self.id
@ -98,6 +111,18 @@ impl ChildRef {
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// Bastion::children(|children| {
@ -114,6 +139,7 @@ impl ChildRef {
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
pub fn is_public(&self) -> bool {
self.is_public
@ -135,7 +161,18 @@ impl ChildRef {
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// // The message that will be "told"...
/// const TELL_MSG: &'static str = "A message containing data (tell).";
@ -195,7 +232,18 @@ impl ChildRef {
/// ```
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// // The message that will be "asked"...
/// const ASK_MSG: &'static str = "A message containing data (ask).";
@ -277,6 +325,18 @@ impl ChildRef {
/// ```
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// # let children_ref =
/// # Bastion::children(|children| {
@ -304,6 +364,7 @@ impl ChildRef {
/// #
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
pub fn stop(&self) -> Result<(), ()> {
debug!("ChildRef({}): Stopping.", self.id);
@ -323,6 +384,18 @@ impl ChildRef {
/// ```
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// # let children_ref = Bastion::children(|children| children).unwrap();
@ -332,6 +405,7 @@ impl ChildRef {
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
pub fn kill(&self) -> Result<(), ()> {
debug!("ChildRef({}): Killing.", self.id());

View File

@ -49,6 +49,18 @@ use tracing::{debug, trace, warn};
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// let children_ref: ChildrenRef = Bastion::children(|children| {
@ -70,6 +82,7 @@ use tracing::{debug, trace, warn};
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
///
/// [`with_redundancy`]: #method.with_redundancy
@ -157,6 +170,18 @@ impl Children {
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// Bastion::children(|children| {
@ -168,6 +193,7 @@ impl Children {
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
pub fn id(&self) -> &BastionId {
self.bcast.id()
@ -244,6 +270,18 @@ impl Children {
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// Bastion::children(|children| {
@ -263,6 +301,7 @@ impl Children {
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
pub fn with_exec<I, F>(mut self, init: I) -> Self
where
@ -290,6 +329,18 @@ impl Children {
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// Bastion::children(|children| {
@ -300,6 +351,7 @@ impl Children {
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
///
/// [`with_exec`]: #method.with_exec
@ -336,6 +388,18 @@ impl Children {
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// Bastion::children(|children| {
@ -348,6 +412,7 @@ impl Children {
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
/// [`DispatcherHandler`]: ../dispatcher/trait.DispatcherHandler.html
pub fn with_dispatcher(mut self, dispatcher: Dispatcher) -> Self {
@ -369,7 +434,18 @@ impl Children {
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// Bastion::children(|children| {
@ -409,6 +485,18 @@ impl Children {
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// Bastion::children(|children| {
@ -431,6 +519,7 @@ impl Children {
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
///
/// [`Callbacks`]: struct.Callbacks.html
@ -458,6 +547,18 @@ impl Children {
/// # use bastion::prelude::*;
/// # use std::time::Duration;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// Bastion::children(|children| {
@ -476,6 +577,7 @@ impl Children {
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
/// [`std::time::Duration`]: https://doc.rust-lang.org/nightly/core/time/struct.Duration.html
pub fn with_heartbeat_tick(mut self, interval: Duration) -> Self {

View File

@ -52,6 +52,18 @@ impl ChildrenRef {
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// let children_ref = Bastion::children(|children| {
@ -64,6 +76,7 @@ impl ChildrenRef {
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
pub fn id(&self) -> &BastionId {
&self.id
@ -77,6 +90,18 @@ impl ChildrenRef {
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// # let children_ref = Bastion::children(|children| children).unwrap();
@ -85,6 +110,7 @@ impl ChildrenRef {
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
///
/// [`ChildRef`]: children/struct.ChildRef.html
@ -100,6 +126,18 @@ impl ChildrenRef {
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// # let children_ref = Bastion::children(|children| children).unwrap();
@ -108,6 +146,7 @@ impl ChildrenRef {
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
///
/// [`ChildRef`]: children/struct.ChildRef.html
@ -135,7 +174,18 @@ impl ChildrenRef {
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// # let children_ref = Bastion::children(|children| children).unwrap();
@ -191,6 +241,18 @@ impl ChildrenRef {
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// # let children_ref = Bastion::children(|children| children).unwrap();
@ -199,6 +261,7 @@ impl ChildrenRef {
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
pub fn stop(&self) -> Result<(), ()> {
debug!("ChildrenRef({}): Stopping.", self.id());
@ -219,6 +282,18 @@ impl ChildrenRef {
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// # let children_ref = Bastion::children(|children| children).unwrap();
@ -227,6 +302,7 @@ impl ChildrenRef {
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
pub fn kill(&self) -> Result<(), ()> {
debug!("ChildrenRef({}): Killing.", self.id());

View File

@ -10,6 +10,18 @@
/// ```rust
/// use bastion::prelude::*;
///
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// let config = Config::new().show_backtraces();
///
/// Bastion::init_with(config);
@ -19,6 +31,7 @@
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
///
/// [`Bastion::init_with`]: struct.Bastion.html#method.init_with
@ -57,6 +70,18 @@ impl Config {
/// ```rust
/// use bastion::prelude::*;
///
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// let config = Config::new().show_backtraces();
///
/// Bastion::init_with(config);
@ -67,6 +92,7 @@ impl Config {
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
pub fn show_backtraces(mut self) -> Self {
self.backtraces = Backtraces::show();
@ -83,6 +109,18 @@ impl Config {
/// ```rust
/// use bastion::prelude::*;
///
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// let config = Config::new().hide_backtraces();
///
/// Bastion::init_with(config);
@ -93,6 +131,7 @@ impl Config {
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
///
/// [`Config::show_backtraces`]: #method.show_backtraces

View File

@ -42,6 +42,18 @@ pub const NIL_ID: BastionId = BastionId(Uuid::nil());
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// Bastion::children(|children| {
@ -57,6 +69,7 @@ pub const NIL_ID: BastionId = BastionId(Uuid::nil());
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
pub struct BastionId(pub(crate) Uuid);
@ -71,6 +84,18 @@ pub struct BastionId(pub(crate) Uuid);
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// Bastion::children(|children| {
@ -103,6 +128,7 @@ pub struct BastionId(pub(crate) Uuid);
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
pub struct BastionContext {
id: BastionId,
@ -155,6 +181,18 @@ impl BastionContext {
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// Bastion::children(|children| {
@ -172,6 +210,7 @@ impl BastionContext {
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
///
/// [`ChildRef`]: children/struct.ChildRef.html
@ -187,6 +226,18 @@ impl BastionContext {
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// Bastion::children(|children| {
@ -204,6 +255,7 @@ impl BastionContext {
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
///
/// [`ChildrenRef`]: children/struct.ChildrenRef.html
@ -222,6 +274,18 @@ impl BastionContext {
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// // When calling the method from a children group supervised
@ -258,6 +322,7 @@ impl BastionContext {
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
///
/// [`SupervisorRef`]: supervisor/struct.SupervisorRef.html
@ -283,6 +348,18 @@ impl BastionContext {
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// Bastion::children(|children| {
@ -300,6 +377,7 @@ impl BastionContext {
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
///
/// [`recv`]: #method.recv
@ -339,6 +417,18 @@ impl BastionContext {
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// Bastion::children(|children| {
@ -355,6 +445,7 @@ impl BastionContext {
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
///
/// [`try_recv`]: #method.try_recv
@ -390,6 +481,18 @@ impl BastionContext {
/// # use bastion::prelude::*;
/// # use std::time::Duration;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// Bastion::children(|children| {
@ -411,6 +514,7 @@ impl BastionContext {
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
///
/// [`recv`]: #method.recv
@ -439,6 +543,18 @@ impl BastionContext {
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
///
@ -455,6 +571,7 @@ impl BastionContext {
/// #
/// # Bastion::start();
/// # Bastion::block_until_stopped();
/// # }
/// ```
///
/// [`RefAddr`]: /prelude/struct.Answer.html
@ -477,6 +594,18 @@ impl BastionContext {
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// Bastion::children(|children| {
@ -496,6 +625,7 @@ impl BastionContext {
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
///
/// [`RefAddr`]: ../prelude/struct.RefAddr.html
@ -529,7 +659,18 @@ impl BastionContext {
/// ```
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// // The message that will be "asked"...
/// const ASK_MSG: &'static str = "A message containing data (ask).";
@ -699,7 +840,22 @@ mod context_tests {
use crate::Bastion;
use std::panic;
#[test]
#[cfg(feature = "tokio-runtime")]
mod tokio_tests {
#[tokio::test]
async fn test_context() {
super::test_context()
}
}
#[cfg(not(feature = "tokio-runtime"))]
mod no_tokio_tests {
#[test]
fn test_context() {
super::test_context()
}
}
fn test_context() {
Bastion::init();
Bastion::start();

View File

@ -22,6 +22,18 @@ pub(crate) struct Envelope {
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// Bastion::children(|children| {
@ -37,6 +49,7 @@ pub(crate) struct Envelope {
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
pub struct SignedMessage {
pub(crate) msg: Msg,
@ -60,6 +73,18 @@ impl SignedMessage {
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// Bastion::children(|children| {
@ -75,6 +100,7 @@ impl SignedMessage {
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
pub fn signature(&self) -> &RefAddr {
&self.sign
@ -89,6 +115,18 @@ impl SignedMessage {
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// Bastion::children(|children| {
@ -106,6 +144,7 @@ impl SignedMessage {
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
pub struct RefAddr {
path: Arc<BastionPath>,
@ -134,7 +173,18 @@ impl RefAddr {
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// # let children_ref = Bastion::children(|children| children).unwrap();
@ -174,7 +224,18 @@ impl RefAddr {
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// # let children_ref = Bastion::children(|children| children).unwrap();

View File

@ -10,10 +10,23 @@ use std::future::Future;
/// # Example
/// ```
/// # use std::{thread, time};
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// use bastion::executor::blocking;
/// let task = blocking(async move {
/// thread::sleep(time::Duration::from_millis(3000));
/// });
/// # }
/// ```
pub fn blocking<F, R>(future: F) -> RecoverableHandle<R>
where
@ -29,6 +42,18 @@ where
/// # Example
/// ```
/// # use bastion::prelude::*;
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// use bastion::executor::run;
/// let future1 = async move {
/// 123
@ -45,6 +70,7 @@ where
///
/// let result = run(future2);
/// assert_eq!(result, 5);
/// # }
/// ```
pub fn run<F, T>(future: F) -> T
where
@ -58,11 +84,24 @@ where
/// # Example
/// ```
/// # use bastion::prelude::*;
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// use bastion::executor::{spawn, run};
/// let handle = spawn(async {
/// panic!("test");
/// });
/// run(handle);
/// # }
/// ```
pub fn spawn<F, T>(future: F) -> RecoverableHandle<T>
where

View File

@ -8,7 +8,18 @@
///
/// ```
/// # use bastion::prelude::*;
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// let children = children! {
/// // the default redundancy is 1
/// redundancy: 100,
@ -133,7 +144,18 @@ macro_rules! children {
/// # Example
/// ```
/// # use bastion::prelude::*;
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// let sp = supervisor! {
/// callbacks: Callbacks::default(),
/// strategy: SupervisionStrategy::OneForAll,
@ -189,7 +211,18 @@ macro_rules! supervisor {
/// # use std::{thread, time};
/// # use lightproc::proc_stack::ProcStack;
/// # use bastion::prelude::*;
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// let task = blocking! {
/// thread::sleep(time::Duration::from_millis(3000));
/// };
@ -211,7 +244,18 @@ macro_rules! blocking {
/// # Example
/// ```
/// # use bastion::prelude::*;
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// let future1 = async move {
/// 123
/// };
@ -245,7 +289,18 @@ macro_rules! run {
/// # Example
/// ```
/// # use bastion::prelude::*;
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// let handle = spawn! {
/// panic!("test");
/// };

View File

@ -49,7 +49,18 @@ pub struct AnswerSender(oneshot::Sender<SignedMessage>);
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// // The message that will be "asked"...
/// const ASK_MSG: &'static str = "A message containing data (ask).";
@ -125,7 +136,18 @@ pub struct Answer(Receiver<SignedMessage>);
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// Bastion::children(|children| {
/// children.with_exec(|ctx: BastionContext| {
@ -572,7 +594,18 @@ impl Future for Answer {
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// // The message that will be broadcasted...
/// const BCAST_MSG: &'static str = "A message containing data (broadcast).";
@ -776,7 +809,18 @@ macro_rules! msg {
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// # let children_ref =
/// // Create a new child...

View File

@ -17,7 +17,18 @@ use std::result::Result;
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
///
/// # Bastion::children(|children| {
@ -72,7 +83,18 @@ impl BastionPath {
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// # let children_ref = Bastion::children(|children| children).unwrap();
@ -113,7 +135,18 @@ impl BastionPath {
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// # let children_ref = Bastion::children(|children| children).unwrap();
@ -154,7 +187,18 @@ impl BastionPath {
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// # let children_ref = Bastion::children(|children| children).unwrap();
@ -263,6 +307,18 @@ impl fmt::Debug for BastionPath {
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
///
@ -284,6 +340,7 @@ impl fmt::Debug for BastionPath {
/// #
/// # Bastion::start();
/// # Bastion::block_until_stopped();
/// # }
/// ```
pub enum BastionPathElement {
#[doc(hidden)]
@ -333,6 +390,18 @@ impl BastionPathElement {
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
///
/// Bastion::children(|children| {
@ -353,6 +422,7 @@ impl BastionPathElement {
/// #
/// # Bastion::start();
/// # Bastion::block_until_stopped();
/// # }
/// ```
pub fn is_child(&self) -> bool {
matches!(self, BastionPathElement::Child(_))

View File

@ -44,6 +44,18 @@ use tracing::{debug, trace, warn};
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// let sp_ref: SupervisorRef = Bastion::supervisor(|sp| {
@ -55,6 +67,7 @@ use tracing::{debug, trace, warn};
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
///
/// [`Children`]: children/struct.Children.html
@ -358,6 +371,18 @@ impl Supervisor {
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// Bastion::supervisor(|sp| {
@ -370,6 +395,7 @@ impl Supervisor {
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
pub fn id(&self) -> &BastionId {
&self.bcast.id()
@ -414,6 +440,18 @@ impl Supervisor {
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// # Bastion::supervisor(|parent| {
@ -427,6 +465,7 @@ impl Supervisor {
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
///
/// [`SupervisorRef`]: ../struct.SupervisorRef.html
@ -477,6 +516,18 @@ impl Supervisor {
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// # Bastion::supervisor(|mut parent| {
@ -491,6 +542,7 @@ impl Supervisor {
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
///
/// [`SupervisorRef`]: ../struct.SupervisorRef.html
@ -542,6 +594,18 @@ impl Supervisor {
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// # Bastion::supervisor(|sp| {
@ -563,6 +627,7 @@ impl Supervisor {
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
///
/// [`Children`]: children/struct.Children.html
@ -619,6 +684,18 @@ impl Supervisor {
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// # Bastion::supervisor(|mut sp| {
@ -641,6 +718,7 @@ impl Supervisor {
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
///
/// [`Children`]: children/struct.Children.html
@ -708,6 +786,18 @@ impl Supervisor {
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// Bastion::supervisor(|sp| {
@ -718,6 +808,7 @@ impl Supervisor {
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
///
/// [`SupervisionStrategy::OneForOne`]: supervisor/enum.SupervisionStrategy.html#variant.OneForOne
@ -746,6 +837,18 @@ impl Supervisor {
/// # use bastion::prelude::*;
/// # use std::time::Duration;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// # Bastion::supervisor(|sp| {
/// sp.with_restart_strategy(
@ -763,6 +866,7 @@ impl Supervisor {
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
pub fn with_restart_strategy(mut self, restart_strategy: RestartStrategy) -> Self {
trace!(
@ -790,6 +894,18 @@ impl Supervisor {
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// Bastion::supervisor(|sp| {
@ -803,6 +919,7 @@ impl Supervisor {
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
///
/// [`Callbacks`]: struct.Callbacks.html
@ -1400,6 +1517,18 @@ impl SupervisorRef {
/// ```rust
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// let supervisor_ref = Bastion::supervisor(|sp| {
@ -1412,6 +1541,7 @@ impl SupervisorRef {
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
pub fn id(&self) -> &BastionId {
&self.id
@ -1435,6 +1565,18 @@ impl SupervisorRef {
/// ```
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// # let mut parent_ref = Bastion::supervisor(|sp| sp).unwrap();
@ -1447,6 +1589,7 @@ impl SupervisorRef {
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
///
/// [`Supervisor`]: supervisor/struct.Supervisor.html
@ -1498,6 +1641,18 @@ impl SupervisorRef {
/// ```
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// # let sp_ref = Bastion::supervisor(|sp| sp).unwrap();
@ -1518,6 +1673,7 @@ impl SupervisorRef {
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
///
/// [`Children`]: children/struct.Children.html
@ -1596,6 +1752,18 @@ impl SupervisorRef {
/// ```
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// # let sp_ref = Bastion::supervisor(|sp| sp).unwrap();
@ -1605,6 +1773,7 @@ impl SupervisorRef {
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
///
/// [`SupervisionStrategy::OneForOne`]: supervisor/enum.SupervisionStrategy.html#variant.OneForOne
@ -1637,7 +1806,18 @@ impl SupervisorRef {
/// ```
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// # let sp_ref = Bastion::supervisor(|sp| sp).unwrap();
@ -1693,6 +1873,18 @@ impl SupervisorRef {
/// ```
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// # let sp_ref = Bastion::supervisor(|sp| sp).unwrap();
@ -1701,6 +1893,7 @@ impl SupervisorRef {
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
pub fn stop(&self) -> Result<(), ()> {
debug!("SupervisorRef({}): Stopping.", self.id());
@ -1721,6 +1914,18 @@ impl SupervisorRef {
/// ```
/// # use bastion::prelude::*;
/// #
/// # #[cfg(feature = "tokio-runtime")]
/// # #[tokio::main]
/// # async fn main() {
/// # run();
/// # }
/// #
/// # #[cfg(not(feature = "tokio-runtime"))]
/// # fn main() {
/// # run();
/// # }
/// #
/// # fn run() {
/// # Bastion::init();
/// #
/// # let sp_ref = Bastion::supervisor(|sp| sp).unwrap();
@ -1729,6 +1934,7 @@ impl SupervisorRef {
/// # Bastion::start();
/// # Bastion::stop();
/// # Bastion::block_until_stopped();
/// # }
/// ```
pub fn kill(&self) -> Result<(), ()> {
debug!("SupervisorRef({}): Killing.", self.id());

View File

@ -42,11 +42,28 @@ fn spawn_responders() -> ChildrenRef {
.expect("Couldn't create the children group.")
}
#[test]
fn answer_and_tell_signatures() {
setup();
Bastion::spawn(run).unwrap();
teardown();
#[cfg(feature = "tokio-runtime")]
mod tokio_tests {
use super::*;
#[tokio::test]
async fn answer_and_tell_signatures() {
setup();
Bastion::spawn(run).unwrap();
teardown();
}
}
#[cfg(not(feature = "tokio-runtime"))]
mod no_tokio_tests {
use super::*;
#[test]
fn answer_and_tell_signatures() {
setup();
Bastion::spawn(run).unwrap();
teardown();
}
}
async fn run(ctx: BastionContext) -> Result<(), ()> {

View File

@ -0,0 +1,8 @@
# Seeds for failure cases proptest has generated in the past. It is
# automatically read and these particular cases re-run before any
# novel cases are generated.
#
# It is recommended to check this file in to source control so that
# everyone who runs the test benefits from these saved cases.
cc 70c25a250dab8458e4c6eced0bd8d0b0925a85cab0e33fe71a3c527b8b3780c2 # shrinks to message = ""
cc 0ce425dcb58b6d604391a2b073f13559ce8e882abe9aeaa760fe7c97b2f5d610 # shrinks to message = "\u{10a39}🢰ûѨ*<2A> .﹪/3t\\ஞ0\"Ⱥ\'ቒ1"

View File

@ -4,32 +4,53 @@ use std::sync::Once;
static START: Once = Once::new();
proptest! {
#![proptest_config(ProptestConfig::with_cases(1_000))]
#[test]
fn proptest_bcast_message(message in "\\PC*") {
START.call_once(|| {
Bastion::init();
});
Bastion::start();
if let Ok(_chrn) = Bastion::children(|children: Children| {
children
.with_exec(move |ctx: BastionContext| {
async move {
msg! { ctx.recv().await?,
ref _msg: &'static str => {};
// This won't happen because this example
// only "asks" a `&'static str`...
_: _ => {};
}
Ok(())
}
})
}){
let message: &'static str = Box::leak(message.into_boxed_str());
Bastion::broadcast(message).expect("broadcast failed");
#[cfg(feature = "tokio-runtime")]
mod tokio_proptests {
use super::*;
proptest! {
#![proptest_config(ProptestConfig::with_cases(1_000))]
#[test]
fn proptest_bcast_message(message in "\\PC*") {
tokio_test::block_on(async {
super::test_with_message(message);
});
}
}
}
#[cfg(not(feature = "tokio-runtime"))]
mod not_tokio_proptests {
use super::*;
proptest! {
#![proptest_config(ProptestConfig::with_cases(1_000))]
#[test]
fn proptest_bcast_message(message in "\\PC*") {
super::test_with_message(message);
}
}
}
fn test_with_message(message: String) {
START.call_once(|| {
Bastion::init();
});
Bastion::start();
if let Ok(_chrn) = Bastion::children(|children: Children| {
children.with_exec(move |ctx: BastionContext| {
async move {
msg! { ctx.recv().await?,
ref _msg: &'static str => {};
// This won't happen because this example
// only "asks" a `&'static str`...
_: _ => {};
}
Ok(())
}
})
}) {
let message: &'static str = Box::leak(message.into_boxed_str());
Bastion::broadcast(message).expect("broadcast failed");
}
}

View File

@ -0,0 +1,7 @@
# Seeds for failure cases proptest has generated in the past. It is
# automatically read and these particular cases re-run before any
# novel cases are generated.
#
# It is recommended to check this file in to source control so that
# everyone who runs the test benefits from these saved cases.
cc 8428d777018d9727329e319192aecdc1187db6917e2a518fd7fd2e285cae0d8d # shrinks to message = ""

View File

@ -5,42 +5,65 @@ use std::sync::Once;
static START: Once = Once::new();
proptest! {
#![proptest_config(ProptestConfig::with_cases(1_000))]
#[test]
fn proptest_intra_message(message in "\\PC*") {
START.call_once(|| {
Bastion::init();
});
Bastion::start();
#[cfg(feature = "tokio-runtime")]
mod tokio_proptests {
use super::*;
proptest! {
#![proptest_config(ProptestConfig::with_cases(1_000))]
#[test]
fn proptest_intra_message(message in "\\PC*") {
tokio::runtime::Runtime::new().unwrap().block_on(async {
super::test_with_message(message);
let message = Arc::new(message);
let _ = Bastion::children(|children| {
children
.with_exec(move |ctx: BastionContext| {
let message = (*message).clone();
async move {
let message: &'static str = Box::leak(message.into_boxed_str());
let answer = ctx
.ask(&ctx.current().addr(), message)
.expect("Couldn't send the message.");
msg! { ctx.recv().await?,
msg: &'static str =!> {
let _ = answer!(ctx, msg);
};
_: _ => ();
}
msg! { answer.await?,
_msg: &'static str => {};
_: _ => {};
}
Ok(())
}
})
});
});
}
}
}
#[cfg(not(feature = "tokio-runtime"))]
mod not_tokio_proptests {
use super::*;
proptest! {
#![proptest_config(ProptestConfig::with_cases(1_000))]
#[test]
fn proptest_intra_message(message in "\\PC*") {
super::test_with_message(message);
}
}
}
fn test_with_message(message: String) {
START.call_once(|| {
Bastion::init();
});
Bastion::start();
let message = Arc::new(message);
let _ = Bastion::children(|children| {
children.with_exec(move |ctx: BastionContext| {
let message = (*message).clone();
async move {
let message: &'static str = Box::leak(message.into_boxed_str());
let answer = ctx
.ask(&ctx.current().addr(), message)
.expect("Couldn't send the message.");
msg! { ctx.recv().await?,
msg: &'static str =!> {
let _ = answer!(ctx, msg);
};
_: _ => ();
}
msg! { answer.await?,
_msg: &'static str => {};
_: _ => {};
}
Ok(())
}
})
});
}

View File

@ -0,0 +1,8 @@
# Seeds for failure cases proptest has generated in the past. It is
# automatically read and these particular cases re-run before any
# novel cases are generated.
#
# It is recommended to check this file in to source control so that
# everyone who runs the test benefits from these saved cases.
cc 3133d59d522ffc52f22b079bc8288d5886ff9879d77ab2963132823345052892 # shrinks to r = 0
cc 886d80a24e6a7e9241ad63841ded2f66f85d477041f292c5029542de1b38e40e # shrinks to r = 0

View File

@ -4,30 +4,55 @@ use std::sync::Once;
static START: Once = Once::new();
proptest! {
#![proptest_config(ProptestConfig::with_cases(1_000))]
#[test]
fn proptest_redundancy(r in std::usize::MIN..32) {
START.call_once(|| {
Bastion::init();
});
Bastion::start();
#[cfg(feature = "tokio-runtime")]
mod tokio_proptests {
use super::*;
Bastion::children(|children| {
children
// shrink over the redundancy
.with_redundancy(r)
.with_exec(|_ctx: BastionContext| {
async move {
// It's a proptest,
// we just don't want the loop
// to be optimized away
#[allow(clippy::drop_copy)]
loop {
std::mem::drop(());
}
}
})
}).expect("Coudn't spawn children.");
proptest! {
#![proptest_config(ProptestConfig::with_cases(1_000))]
#[test]
fn proptest_redundancy(r in std::usize::MIN..32) {
let _ = tokio_test::task::spawn(async {
super::test_with_usize(r);
});
}
}
}
#[cfg(not(feature = "tokio-runtime"))]
mod not_tokio_proptests {
use super::*;
proptest! {
#![proptest_config(ProptestConfig::with_cases(1_000))]
#[test]
fn proptest_redundancy(r in std::usize::MIN..32) {
super::test_with_usize(r);
}
}
}
fn test_with_usize(r: usize) {
START.call_once(|| {
Bastion::init();
});
Bastion::start();
Bastion::children(|children| {
children
// shrink over the redundancy
.with_redundancy(r)
.with_exec(|_ctx: BastionContext| {
async move {
// It's a proptest,
// we just don't want the loop
// to be optimized away
#[allow(clippy::drop_copy)]
loop {
std::mem::drop(());
}
}
})
})
.expect("Coudn't spawn children.");
}

View File

@ -6,8 +6,23 @@ use std::sync::{
use std::thread;
use std::time::Duration;
#[test]
fn test_run_blocking() {
#[cfg(feature = "tokio-runtime")]
mod tokio_tests {
#[tokio::test]
async fn test_run_blocking() {
super::run()
}
}
#[cfg(not(feature = "tokio-runtime"))]
mod not_tokio_tests {
#[test]
fn test_run_blocking() {
super::run()
}
}
fn run() {
Bastion::init();
Bastion::start();
@ -29,7 +44,6 @@ fn test_run_blocking() {
_: _ => panic!();
}
}
Ok(())
}
})
})

View File

@ -0,0 +1,144 @@
#[cfg(feature = "tokio-runtime")]
mod tokio_tests {
use bastion::prelude::*;
#[tokio::test]
async fn test_simple_await() {
tokio::time::sleep(std::time::Duration::from_nanos(1)).await;
}
#[tokio::test]
async fn test_within_bastion() {
Bastion::init();
Bastion::start();
test_within_children().await;
test_within_message_receive().await;
test_within_message_receive_blocking().await;
test_within_message_receive_spawn().await;
Bastion::stop();
}
async fn test_within_children() {
Bastion::children(|children| {
children.with_exec(|_| async move {
tokio::time::sleep(std::time::Duration::from_nanos(1)).await;
Ok(())
})
})
.expect("Couldn't create the children group.");
}
async fn test_within_message_receive() {
let workers = Bastion::children(|children| {
children.with_exec(|ctx| async move {
msg! {
ctx.recv().await?,
question: &'static str =!> {
if question != "marco" {
panic!("didn't receive expected message");
}
tokio::time::sleep(std::time::Duration::from_nanos(1)).await;
answer!(ctx, "polo").expect("couldn't send answer");
};
_: _ => {
panic!("didn't receive &str");
};
}
Ok(())
})
})
.expect("Couldn't create the children group.");
let answer = workers.elems()[0]
.ask_anonymously("marco")
.expect("Couldn't send the message.");
msg! { answer.await.expect("couldn't receive answer"),
reply: &'static str => {
if reply != "polo" {
panic!("didn't receive expected message");
}
};
_: _ => { panic!("didn't receive &str"); };
}
}
async fn test_within_message_receive_blocking() {
let workers = Bastion::children(|children| {
children.with_exec(|ctx| async move {
msg! {
ctx.recv().await?,
question: &'static str =!> {
if question != "marco" {
panic!("didn't receive expected message");
}
run!(blocking! {
let _ = tokio::time::sleep(std::time::Duration::from_nanos(1)).await;
println!("done");
});
answer!(ctx, "polo").expect("couldn't send answer");
};
_: _ => {
panic!("didn't receive &str");
};
}
Ok(())
})
})
.expect("Couldn't create the children group.");
let answer = workers.elems()[0]
.ask_anonymously("marco")
.expect("Couldn't send the message.");
msg! { answer.await.expect("couldn't receive answer"),
reply: &'static str => {
if reply != "polo" {
panic!("didn't receive expected message");
}
};
_: _ => { panic!("didn't receive &str"); };
}
}
async fn test_within_message_receive_spawn() {
let workers = Bastion::children(|children| {
children.with_exec(|ctx| async move {
msg! {
ctx.recv().await?,
question: &'static str =!> {
if question != "marco" {
panic!("didn't receive expected message");
}
run!(blocking! {
let _ = tokio::time::sleep(std::time::Duration::from_nanos(1)).await;
println!("done");
});
answer!(ctx, "polo").expect("couldn't send answer");
};
_: _ => {
panic!("didn't receive &str");
};
}
Ok(())
})
})
.expect("Couldn't create the children group.");
let answer = workers.elems()[0]
.ask_anonymously("marco")
.expect("Couldn't send the message.");
msg! { answer.await.expect("couldn't receive answer"),
reply: &'static str => {
if reply != "polo" {
panic!("didn't receive expected message");
}
};
_: _ => { panic!("didn't receive &str"); };
}
}
}