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}