use crate::tokio::runtime::Runtime;
use crate::{debugger, Context, Executor};
use ockam_core::compat::sync::Arc;
use ockam_core::flow_control::FlowControls;
#[cfg(feature = "std")]
use ockam_core::OpenTelemetryContext;
use ockam_core::{Address, AllowAll, Mailbox, Mailboxes, LATEST_PROTOCOL_VERSION};
pub struct NullWorker;
impl ockam_core::Worker for NullWorker {
type Context = Context;
type Message = (); }
pub struct NodeBuilder {
logging: bool,
exit_on_panic: bool,
rt: Option<Arc<Runtime>>,
}
impl Default for NodeBuilder {
fn default() -> Self {
Self::new()
}
}
impl NodeBuilder {
pub fn new() -> Self {
Self {
logging: true,
exit_on_panic: true,
rt: None,
}
}
pub fn no_logging(self) -> Self {
Self {
logging: false,
exit_on_panic: self.exit_on_panic,
rt: self.rt,
}
}
pub fn no_exit_on_panic(self) -> Self {
Self {
logging: self.logging,
exit_on_panic: false,
rt: self.rt,
}
}
pub fn with_runtime(self, rt: Arc<Runtime>) -> Self {
Self {
logging: self.logging,
exit_on_panic: self.exit_on_panic,
rt: Some(rt),
}
}
#[inline]
pub fn build(self) -> (Context, Executor) {
if self.logging {
setup_tracing();
}
#[cfg(feature = "std")]
if self.exit_on_panic {
std::panic::set_hook(Box::new(|panic_info| {
let message1 = format!("A fatal error occurred: {panic_info}.");
let message2 = "Please report this issue, with a copy of your logs, to https://github.com/build-trust/ockam/issues.";
error!(message1);
error!(message2);
println!("{}", message1);
println!("{}", message2);
std::process::exit(1);
}));
}
info!("Initializing ockam node");
let flow_controls = FlowControls::new();
let rt = self.rt.unwrap_or_else(|| {
#[cfg(feature = "std")]
{
Arc::new(
tokio::runtime::Builder::new_multi_thread()
.thread_stack_size(1024 * 1024)
.enable_all()
.build()
.expect("cannot initialize the tokio runtime"),
)
}
#[cfg(not(feature = "std"))]
Arc::new(Runtime::new().expect("cannot initialize the tokio runtime"))
});
let mut exe = Executor::new(rt.clone(), &flow_controls);
let addr: Address = "app".into();
let (ctx, sender, _) = Context::new(
LATEST_PROTOCOL_VERSION,
rt.handle().clone(),
exe.sender(),
Mailboxes::new(
Mailbox::new(addr, Arc::new(AllowAll), Arc::new(AllowAll)),
vec![],
),
None,
Default::default(),
&flow_controls,
#[cfg(feature = "std")]
OpenTelemetryContext::current(),
);
debugger::log_inherit_context("NODE", &ctx, &ctx);
exe.initialize_system("app", sender);
(ctx, exe)
}
}
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())
});
let _ = tracing_subscriber::registry()
.with(filter)
.with(tracing_error::ErrorLayer::default())
.with(fmt::layer())
.try_init();
});
}
}