ComponentActor API Reference¶
Category: Reference - Information-oriented
Audience: Developers implementing ComponentActor-based systems
Purpose: Technical specification of ComponentActor traits and methods
Overview¶
ComponentActor is the core integration type bridging WebAssembly components with the airssys-rt actor system. It implements a dual-trait pattern:
- Actor trait: Message handling via mailbox (inter-component communication)
- Child trait: WASM runtime lifecycle management under supervisor control
This architecture enables isolated, sandboxed component execution with actor-based communication patterns.
Architecture Diagram¶
┌────────────────────────────────────┐
│ ComponentActor │
│ ┌──────────────┐ ┌────────────┐ │
│ │ Actor trait │ │ Child trait│ │
│ │ (messaging) │ │ (lifecycle)│ │
│ └──────────────┘ └────────────┘ │
│ ↓ ↓ │
│ ┌──────────────────────────────┐ │
│ │ WasmRuntime (Optional) │ │
│ │ - Wasmtime Engine/Store │ │
│ │ - Component Exports │ │
│ └──────────────────────────────┘ │
└────────────────────────────────────┘
Struct: ComponentActor¶
Type Parameters¶
S: Custom state type (default:()for no state)- Must implement:
Send + Sync + 'static - State is protected by
Arc<RwLock<S>>for concurrent access
Fields¶
| Field | Type | Description |
|---|---|---|
component_id |
ComponentId |
Unique identifier for this component |
wasm_runtime |
Option<WasmRuntime> |
WASM runtime (loaded in Child::start()) |
capabilities |
CapabilitySet |
Security capabilities and permissions |
state |
ActorState |
Current lifecycle state |
metadata |
ComponentMetadata |
Component metadata (name, version, limits) |
mailbox_rx |
Option<UnboundedReceiver<ComponentMessage>> |
Mailbox receiver (managed by ActorSystem) |
created_at |
DateTime<Utc> |
Creation timestamp |
started_at |
Option<DateTime<Utc>> |
Start timestamp (set in Child::start()) |
custom_state |
Arc<RwLock<S>> |
Custom component state |
Performance Characteristics¶
Measured in Task 6.2 (task-004-phase-6-task-6.2-completion-report.md):
- Construction: 286ns (Checkpoint 1,
component_actor_constructionbenchmark) - Full lifecycle (start+stop): 1.49µs (Checkpoint 1,
full_lifecycle_sequencebenchmark) - Memory footprint: < 2MB per instance (target, not yet measured)
Constructor¶
new()¶
Create a new ComponentActor instance with custom state.
Signature:
pub fn new(
component_id: ComponentId,
metadata: ComponentMetadata,
capabilities: CapabilitySet,
initial_state: S,
) -> Self
Parameters:
component_id- Unique identifier for this componentmetadata- Component metadata (name, version, resource limits)capabilities- Security capabilities and permissionsinitial_state- Initial value for custom state (generic type S)
Returns: ComponentActor in ActorState::Creating state
Example:
use airssys_wasm::actor::ComponentActor;
use airssys_wasm::core::{ComponentId, ComponentMetadata, CapabilitySet, ResourceLimits};
let component_id = ComponentId::new("my-component");
let metadata = ComponentMetadata {
name: "my-component".to_string(),
version: "1.0.0".to_string(),
author: "Example Author".to_string(),
description: None,
required_capabilities: vec![],
resource_limits: ResourceLimits {
max_memory_bytes: 64 * 1024 * 1024, // 64MB
max_fuel: 1_000_000, // 1M fuel
max_execution_ms: 5000, // 5s timeout
max_storage_bytes: 10 * 1024 * 1024, // 10MB storage
},
};
let caps = CapabilitySet::new();
// No custom state (default: ())
let actor = ComponentActor::new(component_id, metadata, caps, ());
State Management Methods¶
component_id()¶
Get the component ID.
Signature:
Returns: Reference to the component ID
Example:
state()¶
Get the current actor lifecycle state.
Signature:
Returns: Reference to the current ActorState
Example:
match *actor.state() {
ActorState::Creating => println!("Component is being created"),
ActorState::Ready => println!("Component is ready"),
_ => println!("Component in other state"),
}
is_wasm_loaded()¶
Check if WASM runtime is loaded.
Signature:
Returns: true if Child::start() has successfully loaded the WASM runtime
Example:
uptime()¶
Calculate component uptime.
Signature:
Returns: Duration since Child::start() completed, or None if not started
Example:
if let Some(uptime) = actor.uptime() {
println!("Component uptime: {} seconds", uptime.num_seconds());
}
Custom State Methods¶
with_state()¶
Execute a closure with read-only access to custom state.
Signature:
Parameters:
f- Closure to execute with state reference
Returns: Value returned by the closure
Example:
#[derive(Default)]
struct MyState {
count: u64,
}
let actor: ComponentActor<MyState> = ComponentActor::new(/* ... */, MyState::default());
// Read state
let count = actor.with_state(|state| state.count).await;
with_state_mut()¶
Execute a closure with mutable access to custom state.
Signature:
Parameters:
f- Closure to execute with mutable state reference
Returns: Value returned by the closure
Example:
get_state()¶
Get a clone of the custom state (requires S: Clone).
Signature:
Returns: Cloned copy of the custom state
Example:
set_custom_state()¶
Replace the custom state with a new value.
Signature:
Parameters:
new_state- New state value to set
Returns: The previous state value
Example:
state_arc()¶
Get Arc clone of the custom state RwLock.
Signature:
Returns: Arc-wrapped RwLock of the custom state
Example:
let state_ref = actor.state_arc();
// Share Arc with other tasks
tokio::spawn(async move {
let guard = state_ref.read().await;
// Use state...
});
Communication Methods¶
publish_message()¶
Publish message to topic via MessageBroker.
Signature:
pub async fn publish_message(
&self,
topic: &str,
message: ComponentMessage,
) -> Result<(), WasmError>
Parameters:
topic- Topic name (e.g., "events", "notifications.user")message- ComponentMessage to publish
Returns:
Ok(())- Message published successfullyErr(WasmError::BrokerNotConfigured)- Broker not setErr(WasmError::MessageBrokerError)- Publish failed
Example:
use airssys_wasm::actor::ComponentMessage;
let message = ComponentMessage::InterComponent {
sender: component_id.clone(),
payload: vec![1, 2, 3],
};
actor.publish_message("events.user.login", message).await?;
subscribe_topic()¶
Subscribe to topic for receiving messages.
Signature:
Parameters:
topic- Topic name to subscribe to
Returns:
Ok(SubscriptionHandle)- Subscription successfulErr(WasmError::BrokerNotConfigured)- Broker not set
Example:
send_request()¶
Send request with correlation tracking and timeout (Phase 5 Task 5.1).
Signature:
pub async fn send_request(
&self,
target: &ComponentId,
payload: Vec<u8>,
timeout: std::time::Duration,
) -> Result<tokio::sync::oneshot::Receiver<ResponseMessage>, WasmError>
Parameters:
target- Target component IDpayload- Request payload (multicodec-encoded)timeout- Timeout duration
Returns: Oneshot receiver for response
Performance: 3.18µs roundtrip (Task 6.2 Checkpoint 2, request_response_roundtrip benchmark)
Example:
use std::time::Duration;
let target = ComponentId::new("user-service");
let request = vec![/* multicodec-encoded data */];
let response_rx = actor.send_request(&target, request, Duration::from_secs(5)).await?;
match response_rx.await {
Ok(response) => {
match response.result {
Ok(payload) => println!("Response received"),
Err(e) => eprintln!("Request failed: {}", e),
}
}
Err(_) => eprintln!("Response channel closed"),
}
send_response()¶
Send response to correlated request.
Signature:
pub async fn send_response(
&self,
correlation_id: uuid::Uuid,
result: Result<Vec<u8>, RequestError>,
) -> Result<(), WasmError>
Parameters:
correlation_id- Correlation ID from incoming requestresult- Response payload or error
Returns:
Ok(())- Response sent successfullyErr(WasmError)- Correlation ID not found or tracker not configured
Example:
// Handle incoming request with correlation_id
let response_payload = vec![/* response data */];
actor.send_response(correlation_id, Ok(response_payload)).await?;
Enum: ActorState¶
Actor lifecycle state machine.
Variants:
Creating- Initial state after constructionStarting-Child::start()in progress (loading WASM)Ready- WASM loaded, actor processing messagesStopping-Child::stop()in progress (cleanup)Terminated- Actor stopped, resources releasedFailed(String)- Unrecoverable error occurred
State Transitions:
Creating --[Child::start()]--> Starting --[success]--> Ready
↓
Failed(reason)
Ready --[Child::stop()]--> Stopping --[success]--> Terminated
↓ ↓
Failed(reason) Failed(reason)
Example:
use airssys_wasm::actor::ActorState;
let state = ActorState::Creating;
assert_eq!(state, ActorState::Creating);
let failed = ActorState::Failed("WASM load error".to_string());
match failed {
ActorState::Failed(reason) => println!("Failed: {}", reason),
_ => {}
}
Enum: ComponentMessage¶
Message types for actor communication.
Variants:
Invoke { function: String, args: Vec<u8> }- Call WASM functionInvokeResult { result: Vec<u8>, error: Option<String> }- Function resultInterComponent { sender: ComponentId, payload: Vec<u8> }- Inter-component messageInterComponentWithCorrelation { sender: ComponentId, payload: Vec<u8>, correlation_id: uuid::Uuid }- Request-response messageShutdown- Signal to stop the actorHealthCheck- Request health statusHealthStatus(HealthStatus)- Health status response
Example:
use airssys_wasm::actor::ComponentMessage;
use airssys_wasm::core::ComponentId;
// Invoke WASM function
let msg = ComponentMessage::Invoke {
function: "process_data".to_string(),
args: vec![1, 2, 3, 4], // Multicodec-encoded
};
// Inter-component message
let sender = ComponentId::new("sender-component");
let msg = ComponentMessage::InterComponent {
sender,
payload: vec![0x70, 0x01, 0x00, 0x01], // Multicodec Borsh
};
// Health check
let msg = ComponentMessage::HealthCheck;
Enum: HealthStatus¶
Component health status for monitoring.
Variants:
Healthy- Component operating normallyDegraded { reason: String }- Operational but experiencing issuesUnhealthy { reason: String }- Failed or non-functional
Serialization: Supports Borsh, CBOR, and JSON
Example:
use airssys_wasm::actor::HealthStatus;
use serde_json;
let status = HealthStatus::Degraded {
reason: "High memory usage".to_string(),
};
// JSON serialization
let json = serde_json::to_string(&status).unwrap();
assert!(json.contains("degraded"));
Related Documentation¶
- Lifecycle Hooks API - Lifecycle hook methods and execution order
- Tutorial: Your First ComponentActor - Step-by-step tutorial
- Dual-Trait Design Explanation - Architecture rationale
References¶
- ADR-WASM-006: Component Isolation and Sandboxing (Actor-based approach)
- ADR-RT-004: Actor and Child Trait Separation
- Task 6.2 Performance Report:
task-004-phase-6-task-6.2-completion-report.md