Skip to content

Lifecycle Management

Overview

The LifecycleManager is the central orchestrator responsible for managing the startup and shutdown sequences of all registered BaseService instances in the application.

How It Works

  1. Registration: Services are registered with the LifecycleManager, optionally declaring dependencies on other services.
  2. Startup: When manager.start_all() is called, it builds a dependency graph and starts the services in the correct topological order. It uses asyncio.gather to start independent services concurrently, optimizing startup time.
  3. Readiness: The manager waits for all services to become "ready" by calling their wait_ready() method. The application is only considered fully started after all essential services are ready.
  4. Shutdown: When manager.stop_all() is called, it shuts down all services in the reverse order of their startup, ensuring a graceful teardown.

This system guarantees that a service that depends on a database connection will only start after the database connection manager is ready, preventing race conditions and startup errors.

API Reference

nala.athomic.lifecycle.manager.LifecycleManager

Orchestrates the application lifecycle for all Athomic and Domain services.

Coordinates service startup and shutdown based on priorities. It includes a centralized cache draining phase to ensure all background tasks are persisted before core infrastructure services are stopped.

__init__(domain_initializers_register=None, settings=None, registry=None, cache_handler_cls=None)

Initializes the LifecycleManager.

Parameters:

Name Type Description Default
registry Optional[LifecycleRegistry]

The lifecycle registry to orchestrate. Defaults to the global lifecycle_registry singleton, but can be injected for isolated testing or to run multiple independently-scoped Athomic instances in the same process — the single registry instance plugins write into via on_athomic_startup is the one piece of process-wide state directly reachable by third-party plugin code today.

None
cache_handler_cls Optional[type]

The CacheHandler class (not an instance) used to drain in-flight background cache tasks during shutdown. When None the drain phase is skipped — keeping lifecycle/ free of a hard load-time dependency on performance/ for minimal core deployments that don't use the cache layer. The facade injects this at construction.

None

describe()

Returns a diagnostic snapshot of every registered service, in startup order: name, priority, and current health.

A cheap, immediate alternative to a full runtime-diagnostics framework (EPIC-09 in lifecycle_plugins.md) for answering "why didn't my service start" without instrumenting anything new — it just aggregates BaseService.health(), which every service already exposes.

shutdown() async

Executes the graceful shutdown sequence for all registered services.

The shutdown sequence includes a pre-shutdown phase to drain background cache tasks, followed by stopping services in reverse priority order.

startup() async

Executes the startup sequence for all registered services.

Startup is all-or-nothing: if any service fails to start, every service that already started in this call is stopped again, in reverse order, before the original failure is re-raised — mirroring the rollback semantics BaseManager._connect_once already applies to the clients it manages.

nala.athomic.lifecycle.registry.LifecycleRegistry

Bases: BaseInstanceRegistry[BaseServiceProtocol]

A specialized registry for services with a manageable lifecycle.

This class extends BaseInstanceRegistry by adding a priority system to control the startup and shutdown order of services. Services with a lower priority number are started first and stopped last, which is essential for managing dependencies (e.g., ensuring a database service is available before a repository service that uses it).

Attributes:

Name Type Description
_registry_with_priority List[Tuple[int, str, BaseServiceProtocol]]

An internal list that stores services along with their priority, sorted on insertion.

__init__(protocol)

Initializes the LifecycleRegistry.

Parameters:

Name Type Description Default
protocol BaseServiceProtocol

The protocol that all registered items must conform to.

required

clear() async

Stops all services and completely clears the registry.

This method overrides the parent clear to also purge the internal priority list, ensuring a complete reset for testing or re-initialization.

get_services_by_priority()

Returns all registered services, sorted by startup priority.

Returns:

Type Description
List[BaseServiceProtocol]

List[BaseServiceProtocol]: A list of service instances ordered from

List[BaseServiceProtocol]

lowest to highest priority, ready for startup.

register(name, item_instance, priority=100)

Registers a service instance with a specific priority.

Parameters:

Name Type Description Default
name str

The unique string name for the service instance.

required
item_instance BaseServiceProtocol

The service object to register.

required
priority Optional[int]

The startup priority. Lower numbers are started earlier and stopped later. Defaults to 100.

100