Expand description
ServiceActivator trait: metadata & channel binding intent for a service (activator). Service trait: async-only business logic component.
§Example
use allora_core::{error::Result, service::Service, Exchange, Message};
#[derive(Debug)] struct Echo;
impl Echo { pub fn new() -> Self { Self } }
#[async_trait::async_trait]
impl Service for Echo {
async fn process(&self, exchange: &mut Exchange) -> Result<()> {
if let Some(b) = exchange.in_msg.body_text() { exchange.out_msg = Some(Message::from_text(format!("echo:{b}"))); }
Ok(())
}
}
let svc = Echo::new();
let mut ex = Exchange::new(Message::from_text("hi"));
tokio::runtime::Runtime::new().unwrap().block_on(async { svc.process(&mut ex).await.unwrap(); });
assert_eq!(ex.out_msg.unwrap().body_text(), Some("echo:hi"));§Metadata Accessors
id()– stable identifier (auto-generated or user supplied).from()/to()– declared channel ids for wiring.ref_name()– reference name matching YAMLref-nameand the#[service(name=..)]macro argument (not a file path).
§Implementing
ⓘ
use allora::{service::Service, Exchange, error::Result};
struct UppercaseService;
impl UppercaseService { pub fn new() -> Self { Self } }
#[cfg_attr(feature = "async", async_trait::async_trait)]
impl Service for UppercaseService {
async fn process(&self, exchange: &mut Exchange) -> Result<()> {
if let Some(body) = exchange.in_msg.body_text() { exchange.in_msg.set_body_text(body.to_uppercase()); }
Ok(())
}
}(Single impl with conditional methods; avoids duplication.)
§Future Extensions
- Error classification (e.g. routing vs transformation).
- Lifecycle hooks (
init,shutdown). - Metrics instrumentation via feature flag.
This file intentionally provides only the trait; concrete implementations are user-defined or generated by a future service builder.
Traits§
- Service
- Service
Activator - Internal metadata describing how a service is wired. Users do NOT implement this directly; it is derived from specs.