tap_node/storage/
agent_storage_manager.rs1use crate::error::Result as NodeResult;
7use crate::storage::Storage;
8use dashmap::DashMap;
9use std::path::PathBuf;
10use std::sync::Arc;
11use tracing::{debug, error, info};
12
13#[derive(Clone)]
18pub struct AgentStorageManager {
19 agent_storages: DashMap<String, Arc<Storage>>,
21 tap_root: Option<PathBuf>,
23}
24
25impl AgentStorageManager {
26 pub fn new(tap_root: Option<PathBuf>) -> Self {
28 info!("Creating AgentStorageManager with TAP root: {:?}", tap_root);
29 Self {
30 agent_storages: DashMap::new(),
31 tap_root,
32 }
33 }
34
35 pub async fn get_agent_storage(&self, agent_did: &str) -> NodeResult<Arc<Storage>> {
41 if let Some(storage) = self.agent_storages.get(agent_did) {
43 debug!("Using cached storage for agent: {}", agent_did);
44 return Ok(storage.clone());
45 }
46
47 debug!("Creating new storage for agent: {}", agent_did);
49 let storage = Storage::new_with_did(agent_did, self.tap_root.clone())
50 .await
51 .map_err(|e| {
52 crate::Error::Storage(format!(
53 "Failed to create storage for agent {}: {}",
54 agent_did, e
55 ))
56 })?;
57
58 let storage_arc = Arc::new(storage);
59
60 self.agent_storages
62 .insert(agent_did.to_string(), storage_arc.clone());
63 info!("Created and cached storage for agent: {}", agent_did);
64
65 Ok(storage_arc)
66 }
67
68 pub fn get_cached_agent_storage(&self, agent_did: &str) -> Option<Arc<Storage>> {
70 self.agent_storages.get(agent_did).map(|s| s.clone())
71 }
72
73 pub fn remove_agent_storage(&self, agent_did: &str) -> Option<Arc<Storage>> {
78 debug!("Removing storage cache for agent: {}", agent_did);
79 self.agent_storages
80 .remove(agent_did)
81 .map(|(_, storage)| storage)
82 }
83
84 pub fn cached_storage_count(&self) -> usize {
86 self.agent_storages.len()
87 }
88
89 pub fn cached_agent_dids(&self) -> Vec<String> {
91 self.agent_storages
92 .iter()
93 .map(|entry| entry.key().clone())
94 .collect()
95 }
96
97 pub fn clear_cache(&self) {
102 info!("Clearing all cached agent storage instances");
103 self.agent_storages.clear();
104 }
105
106 pub async fn ensure_agent_storage(&self, agent_did: &str) -> NodeResult<()> {
111 match Storage::new_with_did(agent_did, self.tap_root.clone()).await {
112 Ok(_) => {
113 info!("Ensured storage exists for agent: {}", agent_did);
114 Ok(())
115 }
116 Err(e) => {
117 error!("Failed to ensure storage for agent {}: {}", agent_did, e);
118 Err(crate::Error::Storage(format!(
119 "Failed to ensure storage for agent {}: {}",
120 agent_did, e
121 )))
122 }
123 }
124 }
125}
126
127#[cfg(test)]
128mod tests {
129 use super::*;
130 use tempfile::TempDir;
131
132 #[tokio::test]
133 async fn test_agent_storage_manager_creation() {
134 let temp_dir = TempDir::new().unwrap();
135 let manager = AgentStorageManager::new(Some(temp_dir.path().to_path_buf()));
136
137 assert_eq!(manager.cached_storage_count(), 0);
138 assert!(manager.cached_agent_dids().is_empty());
139 }
140
141 #[tokio::test]
142 async fn test_get_agent_storage() {
143 let temp_dir = TempDir::new().unwrap();
144 let manager = AgentStorageManager::new(Some(temp_dir.path().to_path_buf()));
145
146 let agent_did = "did:example:test-agent";
147
148 let storage1 = manager.get_agent_storage(agent_did).await.unwrap();
150 assert_eq!(manager.cached_storage_count(), 1);
151
152 let storage2 = manager.get_agent_storage(agent_did).await.unwrap();
154 assert_eq!(manager.cached_storage_count(), 1);
155
156 assert!(Arc::ptr_eq(&storage1, &storage2));
158 }
159
160 #[tokio::test]
161 async fn test_remove_agent_storage() {
162 let temp_dir = TempDir::new().unwrap();
163 let manager = AgentStorageManager::new(Some(temp_dir.path().to_path_buf()));
164
165 let agent_did = "did:example:test-agent";
166
167 let _storage = manager.get_agent_storage(agent_did).await.unwrap();
169 assert_eq!(manager.cached_storage_count(), 1);
170
171 let removed = manager.remove_agent_storage(agent_did);
173 assert!(removed.is_some());
174 assert_eq!(manager.cached_storage_count(), 0);
175 }
176
177 #[tokio::test]
178 async fn test_multiple_agents() {
179 let temp_dir = TempDir::new().unwrap();
180 let manager = AgentStorageManager::new(Some(temp_dir.path().to_path_buf()));
181
182 let agent1 = "did:example:agent1";
183 let agent2 = "did:example:agent2";
184
185 let _storage1 = manager.get_agent_storage(agent1).await.unwrap();
187 let _storage2 = manager.get_agent_storage(agent2).await.unwrap();
188
189 assert_eq!(manager.cached_storage_count(), 2);
190
191 let cached_dids = manager.cached_agent_dids();
192 assert!(cached_dids.contains(&agent1.to_string()));
193 assert!(cached_dids.contains(&agent2.to_string()));
194 }
195}