pub trait Reaction: Send + Sync {
// Required methods
fn id(&self) -> &str;
fn type_name(&self) -> &str;
fn properties(&self) -> HashMap<String, Value>;
fn query_ids(&self) -> Vec<String>;
fn initialize<'life0, 'async_trait>(
&'life0 self,
context: ReactionRuntimeContext,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait;
fn start<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait;
fn stop<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait;
fn status<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = ComponentStatus> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait;
// Provided method
fn auto_start(&self) -> bool { ... }
}Expand description
Reaction traits for implementing reaction plugins Trait defining the interface for all reaction implementations.
This is the core abstraction that all reaction plugins must implement. drasi-lib only interacts with reactions through this trait - it has no knowledge of specific plugin types or their configurations.
§Lifecycle
Reactions follow this lifecycle:
- Created by plugin code with configuration
- Added to DrasiLib via
add_reaction()- dependencies injected automatically - Started via
start()(auto-start or manual based onauto_start()) - Stopped via
stop()when no longer needed
§Subscription Model
Reactions manage their own subscriptions to queries using the broadcast channel pattern:
- QueryProvider is injected via
inject_query_provider()at add time - Reactions access queries via
query_provider.get_query_instance() - For each query, reactions call
query.subscribe(reaction_id) - Each subscription provides a broadcast receiver for that query’s results
- Reactions use a priority queue to process results from multiple queries in timestamp order
§Example Implementation
use drasi_lib::{Reaction, QueryProvider};
use drasi_lib::reactions::{ReactionBase, ReactionBaseParams};
use drasi_lib::context::ReactionRuntimeContext;
pub struct MyReaction {
base: ReactionBase,
// Plugin-specific fields
}
impl MyReaction {
pub fn new(config: MyReactionConfig) -> Self {
let params = ReactionBaseParams::new(&config.id, config.queries.clone())
.with_priority_queue_capacity(config.queue_capacity);
Self {
base: ReactionBase::new(params),
}
}
}
#[async_trait]
impl Reaction for MyReaction {
fn id(&self) -> &str {
&self.base.id
}
fn type_name(&self) -> &str {
"my-reaction"
}
fn query_ids(&self) -> Vec<String> {
self.base.queries.clone()
}
async fn initialize(&self, context: ReactionRuntimeContext) {
self.base.initialize(context).await;
}
async fn start(&self) -> Result<()> {
self.base.subscribe_to_queries().await?;
// ... start processing
Ok(())
}
// ... implement other methods
}Required Methods§
Sourcefn properties(&self) -> HashMap<String, Value>
fn properties(&self) -> HashMap<String, Value>
Get the reaction’s configuration properties for inspection
This returns a HashMap representation of the reaction’s configuration for use in APIs and inspection. The actual typed configuration is owned by the plugin - this is just for external visibility.
Sourcefn initialize<'life0, 'async_trait>(
&'life0 self,
context: ReactionRuntimeContext,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn initialize<'life0, 'async_trait>(
&'life0 self,
context: ReactionRuntimeContext,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Initialize the reaction with runtime context.
This method is called automatically by DrasiLib when the reaction is added
via add_reaction(). Plugin developers do not need to call this directly.
The context provides access to:
reaction_id: The reaction’s unique identifierevent_tx: Channel for reporting component lifecycle eventsstate_store: Optional persistent state storagequery_provider: Access to query instances for subscription
Implementation should delegate to self.base.initialize(context).await.
Sourcefn start<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn start<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Start the reaction
The reaction should:
- Subscribe to all configured queries (using injected QueryProvider)
- Start its processing loop
- Update its status to Running
Note: QueryProvider is already available via inject_query_provider() which
is called when the reaction is added to DrasiLib.
Provided Methods§
Sourcefn auto_start(&self) -> bool
fn auto_start(&self) -> bool
Whether this reaction should auto-start when DrasiLib starts
Default is true to match query behavior. Override to return false
if this reaction should only be started manually via start_reaction().
Trait Implementations§
Source§impl Reaction for Box<dyn Reaction + 'static>
Blanket implementation of Reaction for Box<dyn Reaction>
impl Reaction for Box<dyn Reaction + 'static>
Blanket implementation of Reaction for Box<dyn Reaction>
This allows boxed trait objects to be used with methods expecting impl Reaction.
Source§fn properties(&self) -> HashMap<String, Value>
fn properties(&self) -> HashMap<String, Value>
Source§fn auto_start(&self) -> bool
fn auto_start(&self) -> bool
Source§fn initialize<'life0, 'async_trait>(
&'life0 self,
context: ReactionRuntimeContext,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn initialize<'life0, 'async_trait>(
&'life0 self,
context: ReactionRuntimeContext,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn start<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn start<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Implementations on Foreign Types§
Source§impl Reaction for Box<dyn Reaction + 'static>
Blanket implementation of Reaction for Box<dyn Reaction>
impl Reaction for Box<dyn Reaction + 'static>
Blanket implementation of Reaction for Box<dyn Reaction>
This allows boxed trait objects to be used with methods expecting impl Reaction.