pub trait Component:
Send
+ Sync
+ 'static {
type Config: DeserializeOwned + JsonSchema + Send + Sync + 'static;
type Error: StdError + Send + Sync + 'static;
const NAME: &'static str;
// Required method
fn init<'life0, 'life1, 'async_trait>(
cfg: &'life0 Self::Config,
ctx: &'life1 ComponentContext,
) -> Pin<Box<dyn Future<Output = Result<Self, Self::Error>> + Send + 'async_trait>>
where Self: Sized + 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
// Provided methods
fn start<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<(), Self::Error>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait { ... }
fn stop<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<(), Self::Error>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait { ... }
fn health<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = HealthStatus> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait { ... }
fn depends_on() -> &'static [&'static str] { ... }
fn pre_replace_hook<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<(), Self::Error>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait { ... }
fn post_replace_hook<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<(), Self::Error>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait { ... }
}Expand description
The core contract every pluggable runtime element implements.
A Component is:
- Self-describing:
Component::NAMEis a stable identifier used in config files, log spans, and metrics labels. - Schema-validated:
Component::Configimplementsschemars::JsonSchema, so the registry can emit a JSON schema for IDEs and CLI tools. - Lifecycle-bounded: the four-phase
init → start → [serve] → stopcontract lets the registry run a coherent graph of components.
Required Associated Constants§
Required Associated Types§
Sourcetype Config: DeserializeOwned + JsonSchema + Send + Sync + 'static
type Config: DeserializeOwned + JsonSchema + Send + Sync + 'static
Configuration shape. Must be deserializable from JSON/YAML/TOML and must produce a valid JSON Schema for documentation and validation.
Required Methods§
Sourcefn init<'life0, 'life1, 'async_trait>(
cfg: &'life0 Self::Config,
ctx: &'life1 ComponentContext,
) -> Pin<Box<dyn Future<Output = Result<Self, Self::Error>> + Send + 'async_trait>>where
Self: Sized + 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn init<'life0, 'life1, 'async_trait>(
cfg: &'life0 Self::Config,
ctx: &'life1 ComponentContext,
) -> Pin<Box<dyn Future<Output = Result<Self, Self::Error>> + Send + 'async_trait>>where
Self: Sized + 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Construct a component instance from its validated configuration.
Implementations must not perform IO here; defer network and disk
access to Component::start. The ctx provides a shutdown
token that the component can plumb into background tasks.
Provided Methods§
Sourcefn start<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<(), Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn start<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<(), Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Begin serving. Default is a no-op. Override to spawn workers, open connections, or warm caches.
MUST be idempotent: calling start on an already-started component
is a no-op and returns Ok(()).
Sourcefn stop<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<(), Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn stop<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<(), Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Stop serving. Default is a no-op. Override to drain queues, close connections, and persist state.
MUST be idempotent. After stop returns, the component may be
re-start-ed.
Sourcefn health<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = HealthStatus> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn health<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = HealthStatus> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Non-mutating health probe. Default is HealthStatus::healthy.
Override to surface upstream connectivity, queue depth, retry
pressure, etc.
Sourcefn depends_on() -> &'static [&'static str]
fn depends_on() -> &'static [&'static str]
Names of components this component depends on. Used by the registry to build a dependency graph and drive ordered initialization.
Sourcefn pre_replace_hook<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<(), Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn pre_replace_hook<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<(), Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Called before this component is replaced by a new instance.
Default is a no-op. Override to reject new traffic, flush buffers, or signal upstream systems that this instance is about to be swapped out.
The component is still running when this hook fires; in-flight references held by other tasks remain valid.
Sourcefn post_replace_hook<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<(), Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn post_replace_hook<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<(), Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Called after this component has been replaced by a new instance.
Default is a no-op. Override to clean up resources that were
not released during stop, or to notify upstream systems that
the replacement is complete.
At this point, new traffic is routed to the replacement
instance. The old instance may still be held by tasks that
obtained an Arc before the swap.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".