Expand description
§Event System for TAP Node
This module provides a comprehensive event handling and subscription system for TAP Node. The event system allows components to publish and subscribe to various events that occur within the node, enabling loose coupling between components and reactive programming patterns.
§Event Types
The NodeEvent enum defines all the possible events that can be emitted by the TAP Node:
- PlainMessageReceived: When a message is received by an agent
- PlainMessageSent: When a message is sent from an agent to another
- AgentRegistered: When a new agent is registered with the node
- AgentUnregistered: When an agent is removed from the node
- DidResolved: When a DID is resolved (successfully or not)
- AgentPlainMessage: Raw message data intended for an agent
§Subscription Models
The event system supports two subscription models:
- Callback-based: Implementing the
EventSubscribertrait to receive events via callbacks - Channel-based: Using
tokio::sync::broadcastchannels to receive events asynchronously
§Built-in Event Handlers
The event system includes several built-in event handlers:
- EventLogger: Logs all events to a configurable destination (console, file, or custom handler)
§Usage Examples
§Callback-based Subscription
use std::sync::Arc;
use async_trait::async_trait;
use tap_node::event::{EventBus, EventSubscriber, NodeEvent};
// Create a custom event handler
struct LoggingEventHandler;
#[async_trait]
impl EventSubscriber for LoggingEventHandler {
async fn handle_event(&self, event: NodeEvent) {
match event {
NodeEvent::PlainMessageReceived { message } => {
println!("PlainMessage received: {:?}", message);
},
NodeEvent::AgentRegistered { did } => {
println!("Agent registered: {}", did);
},
// Handle other event types...
_ => {}
}
}
}
// Later, subscribe to events
async fn subscribe_events(event_bus: &EventBus) {
let handler = Arc::new(LoggingEventHandler);
event_bus.subscribe(handler).await;
}§Channel-based Subscription
use tap_node::event::{EventBus, NodeEvent};
use tokio::spawn;
async fn monitor_events(event_bus: &EventBus) {
// Get a receiver for the events
let mut receiver = event_bus.subscribe_channel();
// Process events in a separate task
spawn(async move {
while let Ok(event) = receiver.recv().await {
match event {
NodeEvent::PlainMessageSent { message, from, to } => {
println!("PlainMessage sent from {} to {}", from, to);
},
// Handle other events...
_ => {}
}
}
});
}§Using the Event Logger
use std::sync::Arc;
use tap_node::{NodeConfig, TapNode};
use tap_node::event::logger::{EventLogger, EventLoggerConfig, LogDestination};
async fn example() {
// Create a new TAP node
let node = TapNode::new(NodeConfig::default());
// Configure the event logger
let logger_config = EventLoggerConfig {
destination: LogDestination::File {
path: "/var/log/tap-node/events.log".to_string(),
max_size: Some(10 * 1024 * 1024), // 10 MB
rotate: true,
},
structured: true, // Use JSON format
log_level: log::Level::Info,
};
// Create and subscribe the event logger
let event_logger = Arc::new(EventLogger::new(logger_config));
node.event_bus().subscribe(event_logger).await;
}§Thread Safety
The event system is designed to be thread-safe, with all mutable state protected
by appropriate synchronization primitives. The EventBus can be safely shared
across threads using Arc<EventBus>.
Modules§
- logger
- Event Logger for TAP Node
Structs§
- Event
Bus - Event bus for publishing and subscribing to node events
Enums§
- Node
Event - Event types that can be emitted by the TAP Node
Traits§
- Event
Subscriber - Event subscriber trait for receiving node events