mecha10_core/state/
memory_impl.rs1use super::{MemoryStateManager, StateManager, StateOptions, StateSnapshot, VersionedState};
4use crate::error::{Mecha10Error, Result};
5use crate::prelude::now_micros;
6use async_trait::async_trait;
7use serde::{de::DeserializeOwned, Serialize};
8
9#[async_trait]
10impl StateManager for MemoryStateManager {
11 async fn save_with_options<T: Serialize + Send + Sync>(
12 &self,
13 node_id: &str,
14 state: &T,
15 options: StateOptions,
16 ) -> Result<()> {
17 let versioned = if let Some(ttl) = options.ttl {
18 VersionedState::with_ttl(state, options.version, ttl)
19 } else {
20 VersionedState::new(state, options.version)
21 };
22
23 let data = serde_json::to_vec(&versioned).map_err(|e| Mecha10Error::SerializationError {
24 message: format!("Failed to serialize state: {}", e),
25 suggestion: "Ensure state type implements Serialize".to_string(),
26 })?;
27
28 let mut states = self.states.write().await;
29 states.insert(node_id.to_string(), data);
30
31 Ok(())
32 }
33
34 async fn load_versioned<T: DeserializeOwned + Send + Sync>(
35 &self,
36 node_id: &str,
37 ) -> Result<Option<VersionedState<T>>> {
38 let states = self.states.read().await;
39
40 if let Some(data) = states.get(node_id) {
41 let versioned: VersionedState<T> =
42 serde_json::from_slice(data).map_err(|e| Mecha10Error::SerializationError {
43 message: format!("Failed to deserialize state: {}", e),
44 suggestion: "State may be corrupted or type mismatch".to_string(),
45 })?;
46
47 if versioned.is_expired() {
48 return Ok(None);
49 }
50
51 Ok(Some(versioned))
52 } else {
53 Ok(None)
54 }
55 }
56
57 async fn delete(&self, node_id: &str) -> Result<()> {
58 let mut states = self.states.write().await;
59 states.remove(node_id);
60 Ok(())
61 }
62
63 async fn exists(&self, node_id: &str) -> Result<bool> {
64 let states = self.states.read().await;
65 Ok(states.contains_key(node_id))
66 }
67
68 async fn list_nodes(&self) -> Result<Vec<String>> {
69 let states = self.states.read().await;
70 Ok(states.keys().cloned().collect())
71 }
72
73 async fn size(&self, node_id: &str) -> Result<Option<usize>> {
74 let states = self.states.read().await;
75 Ok(states.get(node_id).map(|data| data.len()))
76 }
77
78 async fn create_snapshot(&self, node_id: &str, description: Option<String>) -> Result<StateSnapshot> {
79 let states = self.states.read().await;
80
81 let data = states
82 .get(node_id)
83 .ok_or_else(|| Mecha10Error::Configuration(format!("No state for node: {}", node_id)))?
84 .clone();
85
86 let snapshot = StateSnapshot {
87 id: uuid::Uuid::new_v4().to_string(),
88 node_id: node_id.to_string(),
89 timestamp: now_micros(),
90 description,
91 size_bytes: data.len(),
92 };
93
94 let mut snapshots = self.snapshots.write().await;
95 snapshots.insert(snapshot.id.clone(), (data, snapshot.clone()));
96
97 Ok(snapshot)
98 }
99
100 async fn restore_snapshot(&self, snapshot_id: &str) -> Result<()> {
101 let snapshots = self.snapshots.read().await;
102
103 let (data, snapshot) = snapshots
104 .get(snapshot_id)
105 .ok_or_else(|| Mecha10Error::Configuration(format!("Snapshot not found: {}", snapshot_id)))?;
106
107 let mut states = self.states.write().await;
108 states.insert(snapshot.node_id.clone(), data.clone());
109
110 Ok(())
111 }
112
113 async fn list_snapshots(&self, node_id: &str) -> Result<Vec<StateSnapshot>> {
114 let snapshots = self.snapshots.read().await;
115
116 let mut result: Vec<StateSnapshot> = snapshots
117 .values()
118 .filter_map(|(_, snapshot)| {
119 if snapshot.node_id == node_id {
120 Some(snapshot.clone())
121 } else {
122 None
123 }
124 })
125 .collect();
126
127 result.sort_by_key(|s| s.timestamp);
128 result.reverse();
129
130 Ok(result)
131 }
132
133 async fn delete_snapshot(&self, snapshot_id: &str) -> Result<()> {
134 let mut snapshots = self.snapshots.write().await;
135 snapshots.remove(snapshot_id);
136 Ok(())
137 }
138
139 async fn compare_and_swap<T: Serialize + DeserializeOwned + Send + Sync>(
140 &self,
141 node_id: &str,
142 expected: &T,
143 new: &T,
144 ) -> Result<bool> {
145 let mut states = self.states.write().await;
146
147 if let Some(data) = states.get(node_id) {
148 let current: VersionedState<T> =
149 serde_json::from_slice(data).map_err(|e| Mecha10Error::SerializationError {
150 message: format!("Failed to deserialize for CAS: {}", e),
151 suggestion: "State may be corrupted".to_string(),
152 })?;
153
154 let expected_json = serde_json::to_string(expected).unwrap();
155 let current_json = serde_json::to_string(¤t.data).unwrap();
156
157 if expected_json == current_json {
158 let versioned = VersionedState::new(new, current.version + 1);
159 let new_data = serde_json::to_vec(&versioned).unwrap();
160 states.insert(node_id.to_string(), new_data);
161 Ok(true)
162 } else {
163 Ok(false)
164 }
165 } else {
166 Ok(false)
167 }
168 }
169
170 async fn clear_expired(&self) -> Result<usize> {
171 let mut states = self.states.write().await;
172 let mut expired_keys = Vec::new();
173
174 for (node_id, data) in states.iter() {
175 if let Ok(versioned) = serde_json::from_slice::<VersionedState<serde_json::Value>>(data) {
176 if versioned.is_expired() {
177 expired_keys.push(node_id.clone());
178 }
179 }
180 }
181
182 let count = expired_keys.len();
183 for key in expired_keys {
184 states.remove(&key);
185 }
186
187 Ok(count)
188 }
189}