Skip to main content

NodeConfig

Struct NodeConfig 

Source
pub struct NodeConfig {
    pub tick_interval: Duration,
    pub max_packet_buffer: usize,
    pub max_outgoing_buffer: usize,
    pub max_local_events: usize,
    pub metrics: Option<NodeMetrics>,
    pub observability: Option<ObservabilityConfig>,
    pub health_checks: Option<HealthCheckConfig>,
}
Expand description

ELARA Node configuration

§Observability

The observability field provides unified configuration for all observability components (logging, tracing, metrics). It is optional and disabled by default.

When enabled, observability components are initialized before the node starts:

  • Logging: Structured logs with configurable format and output
  • Tracing: Distributed tracing with OpenTelemetry support
  • Metrics Server: HTTP server exposing Prometheus metrics

§Example with Observability

use elara_runtime::node::NodeConfig;
use elara_runtime::observability::{
    ObservabilityConfig, LoggingConfig, LogLevel, LogFormat, LogOutput,
    MetricsServerConfig
};
use std::time::Duration;

let config = NodeConfig {
    tick_interval: Duration::from_millis(100),
    max_packet_buffer: 1000,
    max_outgoing_buffer: 1000,
    max_local_events: 1000,
    metrics: None,
    observability: Some(ObservabilityConfig {
        logging: Some(LoggingConfig {
            level: LogLevel::Info,
            format: LogFormat::Json,
            output: LogOutput::Stdout,
        }),
        tracing: None,
        metrics_server: Some(MetricsServerConfig {
            bind_address: "0.0.0.0".to_string(),
            port: 9090,
        }),
    }),
};

§Example without Observability (Default)

use elara_runtime::node::NodeConfig;
use std::time::Duration;

let config = NodeConfig {
    tick_interval: Duration::from_millis(100),
    max_packet_buffer: 1000,
    max_outgoing_buffer: 1000,
    max_local_events: 1000,
    metrics: None,
    observability: None, // Observability disabled
};

Fields§

§tick_interval: Duration

Tick interval

§max_packet_buffer: usize

Maximum incoming packet buffer

§max_outgoing_buffer: usize

Maximum outgoing packet buffer

§max_local_events: usize§metrics: Option<NodeMetrics>

Optional metrics for monitoring (None = metrics disabled)

§observability: Option<ObservabilityConfig>

Optional unified observability configuration (None = observability disabled)

When set, this enables structured logging, distributed tracing, and/or metrics server based on the provided configuration. All components are opt-in - set individual fields to None to disable specific components.

Note: This is separate from the metrics field. The metrics field provides direct access to metrics for the node runtime, while observability provides a unified initialization system with HTTP server support.

§health_checks: Option<HealthCheckConfig>

Optional health check configuration (None = health checks disabled)

When set, this enables the health check system with built-in checks for:

  • Connection health (minimum active connections)
  • Memory usage (maximum memory threshold)
  • Time drift (maximum drift from network consensus)
  • State divergence (maximum pending events)

Health checks are opt-in and disabled by default. When enabled, you can configure thresholds for each check and optionally expose HTTP endpoints for Kubernetes probes and load balancers.

§Example

use elara_runtime::node::NodeConfig;
use elara_runtime::health::HealthCheckConfig;
use std::time::Duration;

let config = NodeConfig {
    health_checks: Some(HealthCheckConfig::medium_deployment()),
    ..Default::default()
};

§Production Deployment

Use the preset configurations for common deployment sizes:

  • HealthCheckConfig::small_deployment() - 10 nodes
  • HealthCheckConfig::medium_deployment() - 100 nodes
  • HealthCheckConfig::large_deployment() - 1000 nodes

Or customize thresholds based on your specific requirements:

use elara_runtime::health::HealthCheckConfig;
use std::time::Duration;

let health_config = HealthCheckConfig {
    enabled: true,
    server_bind_address: Some("0.0.0.0:8080".parse().unwrap()),
    cache_ttl: Duration::from_secs(30),
    min_connections: Some(5),
    max_memory_mb: Some(2000),
    max_time_drift_ms: Some(100),
    max_pending_events: Some(1000),
};

Implementations§

Source§

impl NodeConfig

Source

pub fn init_health_checks( &self, node: Arc<Node>, ) -> Option<(Arc<HealthChecker>, Option<JoinHandle<Result<(), Error>>>)>

Initializes health checks based on the configuration.

This method creates a HealthChecker with the configured checks and optionally starts an HTTP server to expose health endpoints.

§Arguments
  • node - Arc reference to the Node for health checks that need node access
§Returns

Returns Some((checker, server_handle)) if health checks are enabled, where:

  • checker is the configured HealthChecker
  • server_handle is Some(JoinHandle) if HTTP server is started, None otherwise

Returns None if health checks are disabled.

§Example
use elara_runtime::node::{Node, NodeConfig};
use elara_runtime::health::HealthCheckConfig;
use std::sync::Arc;

let config = NodeConfig {
    health_checks: Some(HealthCheckConfig::medium_deployment()),
    ..Default::default()
};

let node = Arc::new(Node::with_config(config.clone()));

if let Some((checker, server_handle)) = config.init_health_checks(node) {
    println!("Health checks initialized");
     
    // Check health programmatically
    let status = checker.check_health();
    println!("Health status: {:?}", status.overall);
     
    // Server is running in background (if configured)
    if let Some(handle) = server_handle {
        // Server will run until handle is dropped or joined
    }
}
§HTTP Endpoints

When server_bind_address is configured, the following endpoints are exposed:

  • GET /health - Overall health status

    • Returns 200 OK if healthy or degraded
    • Returns 503 Service Unavailable if unhealthy
  • GET /ready - Readiness probe (Kubernetes)

    • Returns 200 OK if healthy or degraded
    • Returns 503 Service Unavailable if unhealthy
  • GET /live - Liveness probe (Kubernetes)

    • Returns 200 OK if healthy or degraded
    • Returns 503 Service Unavailable if unhealthy
§Panics

Panics if the health check configuration is invalid (fails validation).

Trait Implementations§

Source§

impl Clone for NodeConfig

Source§

fn clone(&self) -> NodeConfig

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for NodeConfig

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for NodeConfig

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FromRef<T> for T
where T: Clone,

Source§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
Source§

impl<T> FromRef<T> for T
where T: Clone,

Source§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
Source§

impl<T> FutureExt for T

Source§

fn with_context(self, otel_cx: Context) -> WithContext<Self>

Attaches the provided Context to this type, returning a WithContext wrapper. Read more
Source§

fn with_current_context(self) -> WithContext<Self>

Attaches the current Context to this type, returning a WithContext wrapper. Read more
Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> IntoRequest<T> for T

Source§

fn into_request(self) -> Request<T>

Wrap the input message T in a tonic::Request
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<A, B, T> HttpServerConnExec<A, B> for T
where B: Body,