Skip to main content

CommandStorage

Trait CommandStorage 

Source
pub trait CommandStorage: Send + Sync {
    // Required methods
    fn publish_command<'life0, 'life1, 'async_trait>(
        &'life0 self,
        command: &'life1 HierarchicalCommand,
    ) -> Pin<Box<dyn Future<Output = Result<String>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn get_command<'life0, 'life1, 'async_trait>(
        &'life0 self,
        command_id: &'life1 str,
    ) -> Pin<Box<dyn Future<Output = Result<Option<HierarchicalCommand>>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn query_commands_by_target<'life0, 'life1, 'async_trait>(
        &'life0 self,
        target_id: &'life1 str,
    ) -> Pin<Box<dyn Future<Output = Result<Vec<HierarchicalCommand>>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn delete_command<'life0, 'life1, 'async_trait>(
        &'life0 self,
        command_id: &'life1 str,
    ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn publish_acknowledgment<'life0, 'life1, 'async_trait>(
        &'life0 self,
        ack: &'life1 CommandAcknowledgment,
    ) -> Pin<Box<dyn Future<Output = Result<String>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn get_acknowledgments<'life0, 'life1, 'async_trait>(
        &'life0 self,
        command_id: &'life1 str,
    ) -> Pin<Box<dyn Future<Output = Result<Vec<CommandAcknowledgment>>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn update_command_status<'life0, 'life1, 'async_trait>(
        &'life0 self,
        status: &'life1 CommandStatus,
    ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn get_command_status<'life0, 'life1, 'async_trait>(
        &'life0 self,
        command_id: &'life1 str,
    ) -> Pin<Box<dyn Future<Output = Result<Option<CommandStatus>>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn observe_commands<'life0, 'life1, 'async_trait>(
        &'life0 self,
        node_id: &'life1 str,
        callback: Box<dyn Fn(HierarchicalCommand) -> Pin<Box<dyn Future<Output = ()> + Send>> + Send + Sync>,
    ) -> Pin<Box<dyn Future<Output = Result<ObserverHandle>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn observe_acknowledgments<'life0, 'life1, 'async_trait>(
        &'life0 self,
        issuer_id: &'life1 str,
        callback: Box<dyn Fn(CommandAcknowledgment) -> Pin<Box<dyn Future<Output = ()> + Send>> + Send + Sync>,
    ) -> Pin<Box<dyn Future<Output = Result<ObserverHandle>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
}
Expand description

Backend-agnostic storage interface for hierarchical commands

This trait abstracts over different CRDT storage backends (Ditto, Automerge/Iroh) and provides the core operations needed for command dissemination.

§Design Principles

  1. Publish-Once Pattern: Each command is published once to the collection
  2. Acknowledge-Many Pattern: Multiple nodes acknowledge a single command
  3. Backend Flexibility: Implementations handle CRDT semantics differently

§Implementation Notes

  • Ditto: Uses DQL INSERT for commands, observer-based subscription for reception
  • Automerge/Iroh: Uses CRDT operations on Automerge documents
  • Both must support observer patterns for real-time command reception

Required Methods§

Source

fn publish_command<'life0, 'life1, 'async_trait>( &'life0 self, command: &'life1 HierarchicalCommand, ) -> Pin<Box<dyn Future<Output = Result<String>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Publish a command to the storage backend

§Arguments
  • command - The hierarchical command to publish
§Returns

Document ID on success

§Errors

Returns error if publish fails (network error, validation failure)

Source

fn get_command<'life0, 'life1, 'async_trait>( &'life0 self, command_id: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<Option<HierarchicalCommand>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Retrieve a command by ID

§Returns

Some(HierarchicalCommand) if found, None if not found

Source

fn query_commands_by_target<'life0, 'life1, 'async_trait>( &'life0 self, target_id: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<Vec<HierarchicalCommand>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Query commands by target

Returns all commands targeting the specified node/squad/platoon

Source

fn delete_command<'life0, 'life1, 'async_trait>( &'life0 self, command_id: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Delete a command (when expired or completed)

Source

fn publish_acknowledgment<'life0, 'life1, 'async_trait>( &'life0 self, ack: &'life1 CommandAcknowledgment, ) -> Pin<Box<dyn Future<Output = Result<String>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Publish an acknowledgment for a command

§Arguments
  • ack - The command acknowledgment to publish
§Returns

Document ID on success

Source

fn get_acknowledgments<'life0, 'life1, 'async_trait>( &'life0 self, command_id: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<Vec<CommandAcknowledgment>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Get all acknowledgments for a command

§Returns

Vector of acknowledgments for the specified command

Source

fn update_command_status<'life0, 'life1, 'async_trait>( &'life0 self, status: &'life1 CommandStatus, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Update command status

§Arguments
  • status - The updated command status
Source

fn get_command_status<'life0, 'life1, 'async_trait>( &'life0 self, command_id: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<Option<CommandStatus>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Get command status

§Returns

Some(CommandStatus) if found, None if not found

Source

fn observe_commands<'life0, 'life1, 'async_trait>( &'life0 self, node_id: &'life1 str, callback: Box<dyn Fn(HierarchicalCommand) -> Pin<Box<dyn Future<Output = ()> + Send>> + Send + Sync>, ) -> Pin<Box<dyn Future<Output = Result<ObserverHandle>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Register a callback for new commands targeting this node

§Arguments
  • node_id - The node ID to filter commands for
  • callback - Async callback invoked when new commands arrive
§Returns

Observer handle (implementation-specific)

§Note

This is the critical method for real-time command reception. Implementations should use native observer patterns (Ditto observers, Automerge subscriptions).

Source

fn observe_acknowledgments<'life0, 'life1, 'async_trait>( &'life0 self, issuer_id: &'life1 str, callback: Box<dyn Fn(CommandAcknowledgment) -> Pin<Box<dyn Future<Output = ()> + Send>> + Send + Sync>, ) -> Pin<Box<dyn Future<Output = Result<ObserverHandle>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Register a callback for new acknowledgments for commands issued by this node

§Arguments
  • issuer_id - The node ID that issued commands
  • callback - Async callback invoked when new acknowledgments arrive

Implementors§