dcs2 0.1.0

An extensible distributed control system framework made in rust with no-std support.
Documentation
use crate::communication::messages::{Package, UpdateClusterVec};
use crate::communication::service::CommunicationService;
use core::fmt::Debug;

use crate::nodes::SystemNodeId;
use crate::rules::measurements::{Measurement, SystemState};
use crate::rules::strategy::Rule;

pub type CoordinationPackage<CoordMessage> = Package<SystemNodeId, CoordMessage>;

/// Stopwatches are used when you need to know when time is up. This is when you need to assert
/// a certain ammount of time has passed
pub trait Stopwatch {
    /// Creates a new instance with the target time as now + `millis`
    fn from_millis(millis: u64) -> Self;
    /// Returns the delta time in secs.
    fn as_secs(&self) -> u64;
    /// Restarts the clock.
    fn restart(&mut self);
    /// Returns true if the time set in [`Stopwatch::from_millis`] has passed
    fn is_timeout(&self) -> bool;
    /// Returns the current stopwatch time expressed as seconds.
    fn current_time_as_secs(&mut self) -> u64;
    /// This is used in case a manual update of the clock is required after each tick or cycle of
    /// the main event loop.
    fn update(&mut self) {}
}

/// Timer gives the current time in seconds
pub trait Timer {
    /// Creates a new instance with the delta set as `millis`
    fn from_millis(millis: u64) -> Self;
    /// Returns the delta time in secs.
    fn as_secs(&self) -> u64;
    /// Waits for the given delta time.
    fn wait(&self);
}

/// This is the main abstraction to be implemented by any coordination algorithm.
pub trait CoordinationService<Clock: Stopwatch, Message: Clone + Debug, Members, Metadata> {
    fn new(id: SystemNodeId, metadata: Metadata) -> Self;

    /// Returns the ID of the cluster leader, or None if it is not set.
    fn leader(&self) -> Option<SystemNodeId>;

    /// Returns the coordinated state of the system
    fn get_state(&self) -> SystemState;

    /// Returns the current rule coordinated by the system
    fn get_current_rule(&self) -> Option<Rule>;

    /// Updates the nodes in the cluster based on [`new_config`].
    fn update_rule(
        &mut self,
        communication_service: &mut dyn CommunicationService<Package<SystemNodeId, Message>>,
        new_rule: Rule,
    );

    /// Updates the nodes in the cluster based on [`new_config`].
    fn update_members(
        &mut self,
        communication_service: &mut dyn CommunicationService<Package<SystemNodeId, Message>>,
        new_config: UpdateClusterVec,
    );

    /// Updates the coordinated state of the system based on `measurement`
    fn update_state(
        &mut self,
        communication_service: &mut dyn CommunicationService<Package<SystemNodeId, Message>>,
        measurement: Measurement,
    );

    /// Receives a message from another node so that the coordination can occur.
    fn process(
        &mut self,
        communication_service: &mut dyn CommunicationService<Package<SystemNodeId, Message>>,
        package: Option<CoordinationPackage<Message>>,
        members: Members,
    );
}