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