Skip to main content

mecha10_core/context/
state_mgmt.rs

1//! Access to the per-node persistent state manager.
2
3use super::Context;
4use crate::error::Result;
5use crate::state::FilesystemStateManager;
6use std::sync::Arc;
7
8impl Context {
9    /// Get or create a state manager for this node
10    ///
11    /// The state manager provides persistent storage for node state across restarts.
12    /// By default, it uses filesystem storage in `./state/` directory.
13    ///
14    /// # Example
15    ///
16    /// ```rust,no_run
17    /// use mecha10_core::prelude::*;
18    /// use serde::{Deserialize, Serialize};
19    ///
20    /// #[derive(Debug, Clone, Serialize, Deserialize)]
21    /// struct MyState {
22    ///     counter: u64,
23    ///     position: (f64, f64),
24    /// }
25    ///
26    /// # async fn example(ctx: &Context) -> Result<()> {
27    /// let state_mgr = ctx.state_manager().await?;
28    ///
29    /// // Load previous state
30    /// let mut state = state_mgr
31    ///     .load::<MyState>("my_node")
32    ///     .await?
33    ///     .unwrap_or(MyState {
34    ///         counter: 0,
35    ///         position: (0.0, 0.0),
36    ///     });
37    ///
38    /// // Update state
39    /// state.counter += 1;
40    ///
41    /// // Save state
42    /// state_mgr.save("my_node", &state).await?;
43    /// # Ok(())
44    /// # }
45    /// ```
46    pub async fn state_manager(&self) -> Result<Arc<crate::state::ConcreteStateManager>> {
47        let mut mgr = self.state_manager.write().await;
48
49        if let Some(existing) = mgr.as_ref() {
50            return Ok(Arc::clone(existing));
51        }
52
53        let state_dir = std::env::var("MECHA10_STATE_DIR").unwrap_or_else(|_| "./state".to_string());
54        let fs_mgr = FilesystemStateManager::new(&state_dir).await?;
55        let arc_mgr = Arc::new(crate::state::ConcreteStateManager::Filesystem(fs_mgr));
56
57        *mgr = Some(Arc::clone(&arc_mgr));
58
59        Ok(arc_mgr)
60    }
61
62    /// Set a custom state manager for this context
63    ///
64    /// This allows using alternative backends (Redis, PostgreSQL, etc.) or custom implementations.
65    ///
66    /// # Example
67    ///
68    /// ```rust,no_run
69    /// use mecha10_core::prelude::*;
70    /// use mecha10_core::state::ConcreteStateManager;
71    /// use std::sync::Arc;
72    ///
73    /// # async fn example(ctx: &Context) -> Result<()> {
74    /// // Use in-memory state manager for testing
75    /// let mem_mgr = Arc::new(ConcreteStateManager::Memory(MemoryStateManager::new()));
76    /// ctx.set_state_manager(mem_mgr).await;
77    /// # Ok(())
78    /// # }
79    /// ```
80    pub async fn set_state_manager(&self, manager: Arc<crate::state::ConcreteStateManager>) {
81        let mut mgr = self.state_manager.write().await;
82        *mgr = Some(manager);
83    }
84}