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
- Publish-Once Pattern: Each command is published once to the collection
- Acknowledge-Many Pattern: Multiple nodes acknowledge a single command
- 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§
Sourcefn 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 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,
Sourcefn 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 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,
Sourcefn 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 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
Sourcefn 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 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)
Sourcefn 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 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,
Sourcefn 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 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,
Sourcefn 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 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,
Sourcefn 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 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,
Sourcefn 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_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 forcallback- 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).
Sourcefn 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,
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 commandscallback- Async callback invoked when new acknowledgments arrive