ServiceManager

Struct ServiceManager 

Source
pub struct ServiceManager { /* private fields */ }
Expand description

Centralized manager for service lifecycles.

The ServiceManager is responsible for:

  • Registering services with configuration
  • Starting services in order
  • Monitoring service health
  • Stopping services gracefully (in reverse order)
  • Broadcasting shutdown signals

§Lifecycle

  1. Register Phase - register() services with config (calls Service::init())
  2. Start Phase - start_all() starts all services (calls Service::start())
  3. Running Phase - Services execute, manager monitors health
  4. Stop Phase - stop_all() stops services in reverse order (calls Service::stop())

§Example

let mut manager = ServiceManager::new();

// Register services (init phase)
manager.register::<MyService>(config).await?;

// Start all services
manager.start_all().await?;

// Check health
let health = manager.health_check_all().await;
for (name, status) in health {
    println!("{}: {:?}", name, status);
}

// Graceful shutdown
manager.stop_all().await?;

Implementations§

Source§

impl ServiceManager

Source

pub fn new() -> Self

Create a new ServiceManager.

§Example
let manager = ServiceManager::new();
Source

pub async fn register<S>(&mut self, config: S::Config) -> Result<()>
where S: Service + 'static,

Register a service with configuration.

Calls Service::init() to initialize the service, then stores it for later startup. Services are started in the order they are registered.

§Arguments
  • config - Service-specific configuration
§Returns
  • Ok(()) - Service registered successfully
  • Err(_) - Service initialization failed
§Example
let mut manager = ServiceManager::new();

// Register HTTP API
manager.register::<HttpApiService>(HttpApiConfig {
    host: "0.0.0.0".to_string(),
    port: 8080,
}).await?;

// Register database
manager.register::<DatabaseService>(DatabaseConfig {
    url: "postgresql://localhost/mecha10".to_string(),
    max_connections: 20,
}).await?;
Source

pub async fn start_all(&mut self) -> Result<()>

Start all registered services.

Services are started in the order they were registered. If any service fails to start, the error is returned and remaining services are not started.

§Returns
  • Ok(()) - All services started successfully
  • Err(_) - A service failed to start
§Example
let mut manager = ServiceManager::new();
// ... register services ...

// Start all services
manager.start_all().await?;

info!("All services started successfully");
Source

pub async fn stop_all(&mut self) -> Result<()>

Stop all services gracefully.

Services are stopped in reverse order of registration. This ensures that dependent services are stopped first (e.g., stop API server before database).

Each service’s stop() method is called, even if previous services failed to stop. All errors are logged, and the first error encountered is returned.

§Returns
  • Ok(()) - All services stopped successfully
  • Err(_) - At least one service failed to stop
§Example
// ... services running ...

// Graceful shutdown
tokio::signal::ctrl_c().await?;
manager.stop_all().await?;
Source

pub async fn health_check_all(&self) -> Vec<(String, HealthStatus)>

Check health of all services.

Calls health_check() on each registered service and returns a vector of (name, status) tuples.

§Returns
  • Vec<(String, HealthStatus)> - Health status for each service
§Example
let health = manager.health_check_all().await;

for (name, status) in health {
    if !status.healthy {
        warn!("Service '{}' is unhealthy: {:?}", name, status.message);
    } else {
        info!("Service '{}' is healthy", name);
    }
}
Source

pub fn shutdown_signal(&self) -> Receiver<()>

Get a broadcast receiver for shutdown signals.

Services can use this to listen for shutdown signals and stop gracefully.

§Returns
  • broadcast::Receiver<()> - Shutdown signal receiver
§Example
let manager = ServiceManager::new();
let mut shutdown_rx = manager.shutdown_signal();

tokio::spawn(async move {
    shutdown_rx.recv().await.ok();
    // Service cleanup...
});
Source

pub fn shutdown(&self)

Trigger shutdown by broadcasting to all listeners.

This sends a signal to all shutdown_signal() receivers. Services should listen to this signal to stop gracefully.

Note: This does NOT call stop_all(). You must call stop_all() separately to actually stop services.

§Example
let mut manager = ServiceManager::new();

// Trigger shutdown signal
manager.shutdown();

// Then stop all services
manager.stop_all().await.ok();
Source

pub fn service_count(&self) -> usize

Get the number of registered services.

§Returns
  • usize - Number of services
§Example
println!("Services registered: {}", manager.service_count());
Source

pub fn service_names(&self) -> Vec<String>

Get names of all registered services.

§Returns
  • Vec<String> - Service names
§Example
let names = manager.service_names();
println!("Services: {}", names.join(", "));

Trait Implementations§

Source§

impl Default for ServiceManager

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more