Skip to main content

composable_runtime/
service.rs

1use std::future::Future;
2use std::pin::Pin;
3use std::sync::Arc;
4
5use anyhow::Result;
6
7use crate::composition::registry::HostCapabilityFactory;
8use crate::config::types::ConfigHandler;
9use crate::types::ComponentInvoker;
10#[cfg(feature = "messaging")]
11use crate::types::MessagePublisher;
12
13/// Lifecycle-managed service that participates in config parsing and runtime.
14///
15/// A service optionally provides a `ConfigHandler` for parsing its own config
16/// categories during the build phase, `HostCapability` implementations for
17/// component linking, and `start`/`shutdown` lifecycle hooks.
18///
19/// The `config_handler()` method returns a separate handler object that can
20/// write parsed config into shared state (e.g. `Arc<Mutex<...>>`). After
21/// config processing, the handler is dropped and the service can read the
22/// accumulated state in its `capabilities()` and `start()` implementations.
23///
24/// Dependencies are injected via `set_*` methods before `start()` is called.
25/// Override only the ones your service needs; all have default no-ops.
26pub trait Service: Send + Sync {
27    /// Provide a config handler for parsing this service's config categories.
28    /// Returns `None` if the service has no config (default).
29    fn config_handler(&self) -> Option<Box<dyn ConfigHandler>> {
30        None
31    }
32
33    /// Provide any HostCapability factories to register (default is empty).
34    /// Called after config parsing and before registry build.
35    /// Each factory creates capability instances from `config.*` values,
36    /// closing over any service-internal state needed by the capability.
37    fn capabilities(&self) -> Vec<(&'static str, HostCapabilityFactory)> {
38        vec![]
39    }
40
41    /// Inject the component invoker. Called before `start()`.
42    /// Override to stash the invoker for use during the service lifecycle.
43    fn set_invoker(&self, _invoker: Arc<dyn ComponentInvoker>) {}
44
45    /// Inject the message publisher. Called before `start()`.
46    /// Override to stash the publisher for use during the service lifecycle.
47    #[cfg(feature = "messaging")]
48    fn set_publisher(&self, _publisher: Arc<dyn MessagePublisher>) {}
49
50    /// Start the service. Called after all dependencies are injected.
51    /// Implementations should spawn background tasks and return immediately.
52    fn start(&self) -> Result<()> {
53        Ok(())
54    }
55
56    /// Shutdown the service, cancelling background tasks.
57    fn shutdown(&self) -> Pin<Box<dyn Future<Output = ()> + Send + '_>> {
58        Box::pin(async {})
59    }
60}