Skip to main content

Component

Trait Component 

Source
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::NAME is a stable identifier used in config files, log spans, and metrics labels.
  • Schema-validated: Component::Config implements schemars::JsonSchema, so the registry can emit a JSON schema for IDEs and CLI tools.
  • Lifecycle-bounded: the four-phase init → start → [serve] → stop contract lets the registry run a coherent graph of components.

Required Associated Constants§

Source

const NAME: &'static str

Stable identifier for the component kind (e.g. "provider.openai", "store.session.redis"). Used in configuration and logging.

Required Associated Types§

Source

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.

Source

type Error: StdError + Send + Sync + 'static

Error type for lifecycle phases. Must implement std::error::Error so the registry can chain and format errors uniformly.

Required Methods§

Source

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§

Source

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(()).

Source

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.

Source

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.

Source

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.

Source

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.

Source

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".

Implementors§