nodo_runtime 0.18.5

Runtime for NODO applications
Documentation
// Copyright 2025 David Weikersdorfer

syntax = "proto3";

package nodo;

// Report about the status of a NODO app
message Report {
    // Metadata information about the app and its node and monitors. Might be sent less frequently
    // to reduce bandwidth.
    AppMeta meta = 1;

    // Current version of the app info. Can be used to detect if previously received app info is
    // still up to date.
    uint64 app_info_version = 2;

    // Status information for each node in the app
    AppStatus status = 3;

    // Statistics for each node in the app
    AppStatistics statistics = 4;

    // Signals of each node in the app
    AppSignals signals = 5;

    // Monitors observing app signals
    AppMonitors monitors = 6;
}

message AppMeta {
    repeated NodeMeta nodes = 1;
    repeated MonitorMeta monitors = 2;
    repeated ScheduleMeta schedules = 3;
}

// Immutable metadata about a node
message NodeMeta {
    // Unique identifier of a node in the app
    uint32 id = 1;

    // The name of the schedule in which the node is executed. There is one schedule per worker.
    string schedule_name = 2;

    // The name of the sequence in which the node is executed. A schedule consists of multiple
    // sequences.
    string sequence_name = 3;

    // The name of the node. The name is guaranteed to be unique across the app
    string node_name = 4;

    // The typename of the codelet used for this node.
    string typename = 5;

    // Names of all RX (receiving) channels of this node.
    repeated string rx_names = 6;

    // Names of all TX (transmitting) channels of this node.
    repeated string tx_names = 7;

    // Names of all signals of this node.
    repeated string signal_names = 8;
}

// Immutable metadata about a monitor
message MonitorMeta {
    // Helpful information text for this monitor
    string info = 1;

    // ID of the node this monitor observes
    uint32 node_id = 2;

    // Gauge this monitor observes
    GaugeKey key = 3;
}

// Immutable metadata about a schedule
message ScheduleMeta {
    uint32 id = 1;

    // The name of the schedule (same as used by NodeMeta)
    string name = 2;

    // Schedule execution period (in seconds). If None than the schedule executes as fast as
    // possible.
    optional float period = 3;
}

message AppStatus {
    repeated NodeStatus nodes = 1;
    repeated ScheduleStatus schedules = 2;
}

// Execution status of a node
message NodeStatus {
    LifecycleStatus lifecycle_status = 3;

    // A textual description of the status returned by the last node execution. This can be a
    // start, step, stop, etc. function.
    string label = 1;

    // Indicates whether the last node execution was considered a skipped execution.
    bool is_skipped = 2;
}

enum LifecycleStatus {
    UNSPECIFIED = 0;
    INACTIVE = 1;
    STARTING = 2;
    RUNNING = 3;
    PAUSING = 4;
    PAUSED = 5;
    RESUMING = 6;
    STOPPING = 7;
    ERROR = 8;
}

// Execution status of a schedule
message ScheduleStatus {
    uint32 id = 1;
    LifecycleStatus lifecycle_status = 2;
    optional float last_period = 3;
    optional string last_error = 4;
    bool has_panicked = 5;
    bool has_finished = 6;
}

message AppStatistics {
    repeated NodeStatistics nodes = 1;
}

// Execution statistics of a node
message NodeStatistics {
    // Various statistics for each node transition function. Node transition function are (in this
    // order): start, step, stop
    repeated TransitionStatistics transitions = 1;

    // Number of currently available messages on each RX channel.
    // Same order as NodeMeta::rx_names
    repeated uint32 rx_available_messages_count = 2;

    // Number of total published messages for each TX channel.
    // Same order as NodeMeta::tx_names
    repeated uint32 tx_published_message_count = 3;

    // Time of last transmitted message since app started
    repeated Duration tx_last_pubtime = 4;
}

// Time elapsed between two time points. Note that Duration is used for pubtime and acqtime which
// are monotonic clocks measuring the time since the app and system booted resp. uint32 can
// represent a duration of more than 100 years which is sufficient for this purpose.
message Duration {
    uint32 secs = 1;
    uint32 nanos = 2;
}

message TransitionStatistics {
    // Statistics about the duration of the execution (begin to end)
    StatisticsSamples duration = 1;

    // Statistics about the period of the execution (begin to begin)
    StatisticsSamples period = 2;

    // Number of executions which are considered skipped.
    uint64 skipped_count = 3;
}

message StatisticsSamples {
    // Total number of samples
    uint64 count = 1;

    // Total duration over all samples
    float total = 2;

    // Minimum duration of all samples. This value is None iff count is 0.
    optional float min_ms = 3;

    // Maximum duration of all samples. This value is None iff count is 0.
    optional float max_ms = 4;
}

message AppSignals {
    repeated NodeSignals nodes = 1;
}

// Signal values for of a node
message NodeSignals {
    repeated NodeSignal signals = 1;
}

// Time and value of a signal
message NodeSignal {
    // Time at which the value was last changed. May be None if value was never set or when the
    // node has not executed yet.
    Duration pubtime = 1;

    // Current value set by the codelet. May be None if value was never set or if the value was
    // explicitely cleared.
    oneof value {
        bool bool = 2;
        int64 int64 = 3;
        uint64 usize = 4;
        double float64 = 5;
        string string = 6;
    }
}

message AppMonitors {
    repeated Monitor monitors = 1;
}

// Information about a monitor observing node gauges (i.e. signals)
message Monitor {
    // Last time the gauge value was changed
    Duration pubtime = 1;

    // Current value of the gauge. Note that the gauge value may not be set in which case this
    // field is None. In case an error occurred when retreiving the gauge value this value is
    // None and the `value_error` is a non-empty string.
    GaugeValue value = 2;

    // Error message in case an error occurred when retreiving the gauge value
    string value_error = 3;

    // Current status of the monitor after evaluating it on the gauge value. If an error occurred
    // while evaluating the monitor the status is set to UNSPECIFIED and `status_error` is a non-
    // -empty string describing the error.
    MonitorStatus status = 4;

    // Error message in case an error occurred while evaluating the monitor
    string status_error = 5;
}

// Key which unique identifies a gauge in the scope of a node. Gauges are observable quantities
// which can be used be monitors.
message GaugeKey {
    // The kind of gauge
    GaugeKeyKind kind = 1;

    // Name of the gauge
    string name = 2;
}

enum GaugeKeyKind {
    GAUGE_KEY_KIND_UNSPECIFIED = 0;

    // Value of a node signal
    GAUGE_KEY_KIND_SIGNAL_VALUE = 1;

    // Last time a node signal was changed
    GAUGE_KEY_KIND_SIGNAL_PUBTIME = 2;

    // Number of messages available on an RX channel (receiver)
    GAUGE_KEY_KIND_RX_AVAILABLE = 3;

    // Number of messages a TX channel (transmitter) has published since the last node start
    GAUGE_KEY_KIND_TX_TOTAL = 4;

    // Last time a TX channel (transmitter) published a message as a pubtime (time elapssed since
    // the app launched).
    GAUGE_KEY_KIND_TX_PUBTIME = 5;
}

message GaugeValue {
    oneof value {
        bool bool = 1;
        int64 int64 = 2;
        uint64 usize = 3;
        double float64 = 4;
        string string = 5;
        Duration pubtime = 6;
        Duration acqtime = 7;
    }
}

enum MonitorStatus {
    MONITOR_STATUS_UNSPECIFIED = 0;

    // The monitored gauge has a nominal value (OK)
    MONITOR_STATUS_NOMINAL = 1;

    // The monitored gauge is out of bounds, but not yet critical
    MONITOR_STATUS_WARNING = 2;

    // The monitored gauge has taken a critical value (error)
    MONITOR_STATUS_CRITICAL = 3;
}