1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
use ockam_core::compat::sync::Arc;
use ockam_core::flow_control::FlowControls;
use ockam_core::{Address, AllowAll, Mailbox, Mailboxes};
use crate::{debugger, Context, Executor};
/// A minimal worker implementation that does nothing
pub struct NullWorker;
impl ockam_core::Worker for NullWorker {
type Context = Context;
type Message = (); // This message type is never used
}
/// Start a node with a custom setup configuration
///
/// The `start_node()` function wraps this type and simply calls
/// `NodeBuilder::default()`. Varying use-cases should use the
/// builder API to customise the underlying node that is created.
pub struct NodeBuilder {
logging: bool,
}
impl Default for NodeBuilder {
fn default() -> Self {
Self::new()
}
}
impl NodeBuilder {
/// Create a node
pub fn new() -> Self {
Self { logging: true }
}
/// Disable logging on this node
pub fn no_logging(self) -> Self {
Self { logging: false }
}
/// Consume this builder and yield a new Ockam Node
#[inline]
pub fn build(self) -> (Context, Executor) {
if self.logging {
setup_tracing();
}
info!("Initializing ockam node");
// Shared instance of FlowControls
let flow_controls = FlowControls::new();
let mut exe = Executor::new(&flow_controls);
let addr: Address = "app".into();
// The root application worker needs a mailbox and relay to accept
// messages from workers, and to buffer incoming transcoded data.
let (ctx, sender, _) = Context::new(
exe.runtime().clone(),
exe.sender(),
Mailboxes::new(
Mailbox::new(addr, Arc::new(AllowAll), Arc::new(AllowAll)),
vec![],
),
None,
Default::default(),
&flow_controls,
);
debugger::log_inherit_context("NODE", &ctx, &ctx);
// Register this mailbox handle with the executor
exe.initialize_system("app", sender);
// Then return the root context and executor
(ctx, exe)
}
}
/// Utility to setup tracing-subscriber from the environment.
///
/// Does nothing if the `no_init_tracing` feature is enabled (for now -- this
/// should be improved, though).
fn setup_tracing() {
#[cfg(feature = "std")]
{
use tracing_subscriber::{filter::LevelFilter, fmt, prelude::*, EnvFilter};
static ONCE: std::sync::Once = std::sync::Once::new();
ONCE.call_once(|| {
let filter = EnvFilter::try_from_env("OCKAM_LOG").unwrap_or_else(|_| {
EnvFilter::default()
.add_directive(LevelFilter::INFO.into())
.add_directive("ockam_node=info".parse().unwrap())
});
// Ignore failure, since we may init externally.
let _ = tracing_subscriber::registry()
.with(filter)
.with(tracing_error::ErrorLayer::default())
.with(fmt::layer())
.try_init();
});
}
}