ProviderAdmin

Trait ProviderAdmin 

Source
pub trait ProviderAdmin:
    Any
    + Send
    + Sync {
    // Required methods
    fn list_instances<'life0, 'async_trait>(
        &'life0 self,
    ) -> Pin<Box<dyn Future<Output = Result<Vec<String>, ProviderError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait;
    fn list_instances_by_status<'life0, 'life1, 'async_trait>(
        &'life0 self,
        status: &'life1 str,
    ) -> Pin<Box<dyn Future<Output = Result<Vec<String>, ProviderError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn list_executions<'life0, 'life1, 'async_trait>(
        &'life0 self,
        instance: &'life1 str,
    ) -> Pin<Box<dyn Future<Output = Result<Vec<u64>, ProviderError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn read_history_with_execution_id<'life0, 'life1, 'async_trait>(
        &'life0 self,
        instance: &'life1 str,
        execution_id: u64,
    ) -> Pin<Box<dyn Future<Output = Result<Vec<Event>, ProviderError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn read_history<'life0, 'life1, 'async_trait>(
        &'life0 self,
        instance: &'life1 str,
    ) -> Pin<Box<dyn Future<Output = Result<Vec<Event>, ProviderError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn latest_execution_id<'life0, 'life1, 'async_trait>(
        &'life0 self,
        instance: &'life1 str,
    ) -> Pin<Box<dyn Future<Output = Result<u64, ProviderError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn get_instance_info<'life0, 'life1, 'async_trait>(
        &'life0 self,
        instance: &'life1 str,
    ) -> Pin<Box<dyn Future<Output = Result<InstanceInfo, ProviderError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn get_execution_info<'life0, 'life1, 'async_trait>(
        &'life0 self,
        instance: &'life1 str,
        execution_id: u64,
    ) -> Pin<Box<dyn Future<Output = Result<ExecutionInfo, ProviderError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn get_system_metrics<'life0, 'async_trait>(
        &'life0 self,
    ) -> Pin<Box<dyn Future<Output = Result<SystemMetrics, ProviderError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait;
    fn get_queue_depths<'life0, 'async_trait>(
        &'life0 self,
    ) -> Pin<Box<dyn Future<Output = Result<QueueDepths, ProviderError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait;
}
Expand description

Administrative capability trait for observability and management operations.

This trait provides rich management and observability features that extend the core Provider functionality. Providers can implement this trait to expose administrative capabilities to the Client.

§Automatic Discovery

The Client automatically discovers this capability through the Provider::as_management_capability() method. When available, management methods become accessible through the client.

§Implementation Guide for LLMs

When implementing a new provider, you can optionally implement this trait to expose management features:

impl Provider for MyProvider {
    // ... implement required Provider methods
     
    fn as_management_capability(&self) -> Option<&dyn ProviderAdmin> {
        Some(self as &dyn ProviderAdmin)
    }
}

impl ProviderAdmin for MyProvider {
    async fn list_instances(&self) -> Result<Vec<String>, String> {
        // Query your storage for all instance IDs
        Ok(vec!["instance-1".to_string(), "instance-2".to_string()])
    }
     
    async fn get_instance_info(&self, instance: &str) -> Result<InstanceInfo, String> {
        // Query instance metadata from your storage
        Ok(InstanceInfo {
            instance_id: instance.to_string(),
            orchestration_name: "ProcessOrder".to_string(),
            orchestration_version: "1.0.0".to_string(),
            current_execution_id: 1,
            status: "Running".to_string(),
            output: None,
            created_at: 1234567890,
            updated_at: 1234567890,
        })
    }
     
    // ... implement other management methods
}

§Required Methods (8 total)

  1. Instance Discovery (2 methods)

    • list_instances() - List all instance IDs
    • list_instances_by_status() - Filter instances by status
  2. Execution Inspection (3 methods)

    • list_executions() - List execution IDs for an instance
    • read_execution() - Read history for a specific execution
    • latest_execution_id() - Get the latest execution ID
  3. Metadata Access (2 methods)

    • get_instance_info() - Get comprehensive instance information
    • get_execution_info() - Get detailed execution information
  4. System Metrics (2 methods)

    • get_system_metrics() - Get system-wide metrics
    • get_queue_depths() - Get current queue depths

§Usage

let client = Client::new(provider);

// Check if management features are available
if client.has_management_capability() {
    let instances = client.list_all_instances().await?;
    let metrics = client.get_system_metrics().await?;
    println!("System has {} instances", metrics.total_instances);
} else {
    println!("Management features not available");
}

Required Methods§

Source

fn list_instances<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<Vec<String>, ProviderError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

List all known instance IDs.

§Returns

Vector of instance IDs, typically sorted by creation time (newest first).

§Use Cases
  • Admin dashboards showing all workflows
  • Bulk operations across instances
  • Testing (verify instance creation)
§Implementation Example
async fn list_instances(&self) -> Result<Vec<String>, String> {
    SELECT instance_id FROM instances ORDER BY created_at DESC
}
Source

fn list_instances_by_status<'life0, 'life1, 'async_trait>( &'life0 self, status: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<Vec<String>, ProviderError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

List instances matching a status filter.

§Parameters
  • status - Filter by execution status: “Running”, “Completed”, “Failed”, “ContinuedAsNew”
§Returns

Vector of instance IDs with the specified status.

§Implementation Example
async fn list_instances_by_status(&self, status: &str) -> Result<Vec<String>, String> {
    SELECT i.instance_id FROM instances i
    JOIN executions e ON i.instance_id = e.instance_id AND i.current_execution_id = e.execution_id
    WHERE e.status = ?
    ORDER BY i.created_at DESC
}
Source

fn list_executions<'life0, 'life1, 'async_trait>( &'life0 self, instance: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<Vec<u64>, ProviderError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

List all execution IDs for an instance.

§Returns

Vector of execution IDs in ascending order: [1], [1, 2], [1, 2, 3], etc.

§Multi-Execution Context

When an orchestration uses ContinueAsNew, multiple executions exist:

  • Execution 1: Original execution
  • Execution 2: First ContinueAsNew
  • Execution 3: Second ContinueAsNew
  • etc.
§Implementation Example
async fn list_executions(&self, instance: &str) -> Result<Vec<u64>, String> {
    SELECT execution_id FROM executions
    WHERE instance_id = ?
    ORDER BY execution_id
}
Source

fn read_history_with_execution_id<'life0, 'life1, 'async_trait>( &'life0 self, instance: &'life1 str, execution_id: u64, ) -> Pin<Box<dyn Future<Output = Result<Vec<Event>, ProviderError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Read the full event history for a specific execution within an instance.

§Parameters
  • instance - The ID of the orchestration instance.
  • execution_id - The specific execution ID to read history for.
§Returns

Vector of events in chronological order (oldest first).

§Implementation Example
async fn read_execution(&self, instance: &str, execution_id: u64) -> Result<Vec<Event>, String> {
    SELECT event_data FROM history
    WHERE instance_id = ? AND execution_id = ?
    ORDER BY event_id
}
Source

fn read_history<'life0, 'life1, 'async_trait>( &'life0 self, instance: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<Vec<Event>, ProviderError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Read the full event history for the latest execution of an instance.

§Parameters
  • instance - The ID of the orchestration instance.
§Returns

Vector of events in chronological order (oldest first) for the latest execution.

§Implementation

This method gets the latest execution ID and delegates to read_history_with_execution_id.

async fn read_history(&self, instance: &str) -> Result<Vec<Event>, ProviderError> {
    let execution_id = self.latest_execution_id(instance).await?;
    self.read_history_with_execution_id(instance, execution_id).await
}
Source

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

Get the latest (current) execution ID for an instance.

§Parameters
  • instance - The ID of the orchestration instance.
§Implementation Pattern
async fn latest_execution_id(&self, instance: &str) -> Result<u64, String> {
    SELECT COALESCE(MAX(execution_id), 1) FROM executions WHERE instance_id = ?
}
Source

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

Get comprehensive information about an instance.

§Parameters
  • instance - The ID of the orchestration instance.
§Returns

Detailed instance information including status, output, and metadata.

§Implementation Example
async fn get_instance_info(&self, instance: &str) -> Result<InstanceInfo, String> {
    SELECT i.*, e.status, e.output
    FROM instances i
    JOIN executions e ON i.instance_id = e.instance_id AND i.current_execution_id = e.execution_id
    WHERE i.instance_id = ?
}
Source

fn get_execution_info<'life0, 'life1, 'async_trait>( &'life0 self, instance: &'life1 str, execution_id: u64, ) -> Pin<Box<dyn Future<Output = Result<ExecutionInfo, ProviderError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Get detailed information about a specific execution.

§Parameters
  • instance - The ID of the orchestration instance.
  • execution_id - The specific execution ID.
§Returns

Detailed execution information including status, output, and event count.

§Implementation Example
async fn get_execution_info(&self, instance: &str, execution_id: u64) -> Result<ExecutionInfo, String> {
    SELECT e.*, COUNT(h.event_id) as event_count
    FROM executions e
    LEFT JOIN history h ON e.instance_id = h.instance_id AND e.execution_id = h.execution_id
    WHERE e.instance_id = ? AND e.execution_id = ?
    GROUP BY e.execution_id
}
Source

fn get_system_metrics<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<SystemMetrics, ProviderError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Get system-wide metrics for the orchestration engine.

§Returns

System metrics including instance counts, execution counts, and status breakdown.

§Implementation Example
async fn get_system_metrics(&self) -> Result<SystemMetrics, String> {
    SELECT
        COUNT(*) as total_instances,
        SUM(CASE WHEN e.status = 'Running' THEN 1 ELSE 0 END) as running_instances,
        SUM(CASE WHEN e.status = 'Completed' THEN 1 ELSE 0 END) as completed_instances,
        SUM(CASE WHEN e.status = 'Failed' THEN 1 ELSE 0 END) as failed_instances
    FROM instances i
    JOIN executions e ON i.instance_id = e.instance_id AND i.current_execution_id = e.execution_id
}
Source

fn get_queue_depths<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<QueueDepths, ProviderError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Get the current depths of the internal work queues.

§Returns

Queue depths for orchestrator and worker queues.

Note: Timer queue depth is not applicable since timers are handled via delayed visibility in the orchestrator queue.

§Implementation Example
async fn get_queue_depths(&self) -> Result<QueueDepths, String> {
    SELECT
        (SELECT COUNT(*) FROM orchestrator_queue WHERE lock_token IS NULL) as orchestrator_queue,
        (SELECT COUNT(*) FROM worker_queue WHERE lock_token IS NULL) as worker_queue
}

Implementors§