Skip to main content

aa_core/storage/
lifecycle_store.rs

1//! [`LifecycleStore`] — agent register / heartbeat / deregister bookkeeping.
2
3use super::{AgentId, Result};
4use async_trait::async_trait;
5
6/// Tracks agent liveness through register, heartbeat, and deregister.
7///
8/// The runtime [`register`](LifecycleStore::register)s an agent when it comes
9/// online, sends periodic [`heartbeat`](LifecycleStore::heartbeat)s while it runs,
10/// and [`deregister`](LifecycleStore::deregister)s it on clean shutdown. Backends
11/// use the heartbeat timestamp to expire agents that stopped reporting.
12///
13/// # Example
14///
15/// ```
16/// use aa_core::storage::{AgentId, LifecycleStore, Result};
17/// use async_trait::async_trait;
18///
19/// /// A store that accepts all lifecycle transitions and persists nothing.
20/// struct NullLifecycleStore;
21///
22/// #[async_trait]
23/// impl LifecycleStore for NullLifecycleStore {
24///     async fn register(&self, _agent_id: &AgentId) -> Result<()> {
25///         Ok(())
26///     }
27///
28///     async fn heartbeat(&self, _agent_id: &AgentId) -> Result<()> {
29///         Ok(())
30///     }
31///
32///     async fn deregister(&self, _agent_id: &AgentId) -> Result<()> {
33///         Ok(())
34///     }
35/// }
36/// ```
37#[async_trait]
38pub trait LifecycleStore: Send + Sync {
39    /// Record that `agent_id` is now online.
40    ///
41    /// Overwrites any stale registration for the same agent.
42    async fn register(&self, agent_id: &AgentId) -> Result<()>;
43
44    /// Refresh the liveness timestamp for `agent_id`.
45    ///
46    /// Returns [`StorageError::NotFound`](super::StorageError::NotFound) when the
47    /// agent is not currently registered.
48    async fn heartbeat(&self, agent_id: &AgentId) -> Result<()>;
49
50    /// Record that `agent_id` has gone offline.
51    ///
52    /// Idempotent: deregistering an agent that is not registered succeeds.
53    async fn deregister(&self, agent_id: &AgentId) -> Result<()>;
54}