pub trait NodeImpl:
Send
+ Sync
+ Debug
+ 'static {
type Config: DeserializeOwned + Send + Sync + Debug;
const NODE_TYPE: Option<NodeType> = None;
const NODE_TAGS: &'static [NodeTag] = _;
const CRATE_NAME: Option<&'static str> = None;
const DESCRIPTION: &'static str = "";
const DEFAULT_RUN_TARGET: &'static str = "robot";
const CATALOG_TAGS: &'static [&'static str] = _;
// Required methods
fn init<'async_trait>(
config: Self::Config,
) -> Pin<Box<dyn Future<Output = Result<Self>> + Send + 'async_trait>>
where Self: Sized + 'async_trait;
fn run<'life0, 'life1, 'async_trait>(
&'life0 mut self,
ctx: &'life1 Context,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
// Provided methods
fn shutdown<'life0, 'async_trait>(
&'life0 mut self,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait { ... }
fn health_check<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = HealthStatus> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait { ... }
fn health_diagnostics(&self) -> Option<HashMap<String, String>> { ... }
fn preflight(&self) -> Result<()> { ... }
}Provided Associated Constants§
const NODE_TYPE: Option<NodeType> = None
const NODE_TAGS: &'static [NodeTag] = _
Sourceconst CRATE_NAME: Option<&'static str> = None
const CRATE_NAME: Option<&'static str> = None
Crate name as it appears in Cargo.toml (e.g. "mecha10-nodes-camera").
None (the default) means this node isn’t meant to be scaffolded via mecha10 add –
e.g. test/example nodes, or any node that hasn’t opted into registration yet. This is
also the gate crate::register_node! checks: a node whose CRATE_NAME is None
registers no crate::node_registry::NodeDescriptor at all, regardless of what its
other registration-related consts are set to.
Sourceconst DESCRIPTION: &'static str = ""
const DESCRIPTION: &'static str = ""
Human-readable one-line description of what this node does, surfaced by a catalog
consumer (e.g. mecha10 add <node>’s listing). Empty by default.
Sourceconst DEFAULT_RUN_TARGET: &'static str = "robot"
const DEFAULT_RUN_TARGET: &'static str = "robot"
Default mecha10 add/run target for this node (e.g. "robot" vs. a simulator-only
target). Defaults to "robot".
Sourceconst CATALOG_TAGS: &'static [&'static str] = _
const CATALOG_TAGS: &'static [&'static str] = _
Free-form catalog search tags (e.g. &["camera", "video", "streaming"]), distinct from
NODE_TAGS (a NodeTag enum used for health-reporting capability tags). Surfaced by a
catalog consumer (e.g. mecha10 add <node>’s search/filtering). Empty by default.
Required Associated Types§
Required Methods§
Sourcefn init<'async_trait>(
config: Self::Config,
) -> Pin<Box<dyn Future<Output = Result<Self>> + Send + 'async_trait>>where
Self: Sized + 'async_trait,
fn init<'async_trait>(
config: Self::Config,
) -> Pin<Box<dyn Future<Output = Result<Self>> + Send + 'async_trait>>where
Self: Sized + 'async_trait,
Initialize the node with the given configuration.
This is called once when the node starts. Use this to:
- Load configuration
- Initialize resources (models, connections, etc.)
- Validate prerequisites
§Errors
Return an error if initialization fails. The node will not start.
Sourcefn run<'life0, 'life1, 'async_trait>(
&'life0 mut self,
ctx: &'life1 Context,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn run<'life0, 'life1, 'async_trait>(
&'life0 mut self,
ctx: &'life1 Context,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Main execution loop for the node.
This is where your node’s business logic lives. Typical patterns:
- Subscribe to topics and process messages
- Run periodic tasks
- Publish results
This method should run indefinitely until:
- The context is cancelled (shutdown requested)
- An unrecoverable error occurs
§Errors
Return an error if the node encounters an unrecoverable error. The node will transition to Error state and shutdown.
Provided Methods§
Sourcefn shutdown<'life0, 'async_trait>(
&'life0 mut self,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn shutdown<'life0, 'async_trait>(
&'life0 mut self,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Graceful shutdown hook.
Called when the node is shutting down. Use this to:
- Close connections
- Flush buffers
- Save state
- Release resources
The default implementation does nothing.
§Errors
Errors during shutdown are logged but don’t prevent shutdown.
Sourcefn health_check<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = HealthStatus> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn health_check<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = HealthStatus> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Health check for monitoring.
Called periodically to check node health. Use this to:
- Report current state
- Check resource usage
- Validate connections
The default implementation returns healthy status.
Sourcefn health_diagnostics(&self) -> Option<HashMap<String, String>>
fn health_diagnostics(&self) -> Option<HashMap<String, String>>
Extra diagnostic key/value pairs to attach to this node’s health report (surfaced on
the wire as crate::messages::system::HealthStatus::diagnostics).
Separate from health_check()’s HealthStatus (which has a fixed shape shared by every
node) so a node can report open-ended, node-specific data – e.g. video-streamer
reports which camera_id(s) it’s actually streaming, since that’s a per-camera identity
distinct from this node’s own node_id/instance_id and the dashboard needs it to pair
WebRTC signaling correctly (see packages/nodes/video-streamer/src/lib.rs’s impl).
The default implementation reports nothing.
Sourcefn preflight(&self) -> Result<()>
fn preflight(&self) -> Result<()>
Node-specific pre-run content check.
This is the “prerun” layer that catches a bad node config before the
node’s main loop starts, rather than crashing deep inside run() – e.g.
a camera device path that doesn’t exist, a model file that was never
downloaded, or two GPIO pins wired to the same physical pin.
Called once, after init() has already produced a fully-typed (and, per
crate::config::Validate, schema/shape-validated) Self, and before
run() starts. Unlike Validate::validate() – which only sees the raw
deserialized config and runs during config loading – preflight() runs
on the initialized node, so it can also check state derived during
init() (e.g. a resolved file path) rather than just raw config fields.
The default implementation does nothing, so opting in is non-breaking for
every existing NodeImpl.
§Errors
Return an error with an actionable message (see node-runner’s
preflight.rs for the established convention: a ❌ header naming what
failed, followed by numbered remediation steps) if the node should not
start. The node will not run.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".