ricecoder_orchestration/managers/
orchestration_manager.rs1use crate::error::Result;
4use crate::models::Workspace;
5use std::path::PathBuf;
6use std::sync::Arc;
7use tokio::sync::RwLock;
8use tracing::{debug, info};
9
10pub struct OrchestrationManager {
16 workspace: Arc<RwLock<Workspace>>,
18
19 workspace_root: PathBuf,
21}
22
23impl OrchestrationManager {
24 pub fn new(workspace_root: PathBuf) -> Self {
34 debug!("Creating OrchestrationManager for workspace: {:?}", workspace_root);
35
36 let workspace = Workspace {
37 root: workspace_root.clone(),
38 ..Default::default()
39 };
40
41 Self {
42 workspace: Arc::new(RwLock::new(workspace)),
43 workspace_root,
44 }
45 }
46
47 pub async fn get_workspace(&self) -> Workspace {
53 self.workspace.read().await.clone()
54 }
55
56 pub async fn set_workspace(&self, workspace: Workspace) {
62 info!("Updating workspace state");
63 *self.workspace.write().await = workspace;
64 }
65
66 pub fn workspace_root(&self) -> &PathBuf {
72 &self.workspace_root
73 }
74
75 pub async fn initialize(&self) -> Result<()> {
84 info!("Initializing OrchestrationManager");
85
86 let mut workspace = self.workspace.write().await;
88 workspace.root = self.workspace_root.clone();
89
90 self.load_configuration(&mut workspace).await?;
92
93 debug!("OrchestrationManager initialized successfully");
94 Ok(())
95 }
96
97 async fn load_configuration(&self, workspace: &mut Workspace) -> Result<()> {
110 debug!("Loading workspace configuration from: {:?}", self.workspace_root);
111
112 let config_paths = vec![
114 self.workspace_root.join(".ricecoder").join("workspace.yaml"),
115 self.workspace_root.join(".ricecoder").join("workspace.json"),
116 self.workspace_root.join("ricecoder.yaml"),
117 self.workspace_root.join("ricecoder.json"),
118 ];
119
120 for config_path in config_paths {
121 if config_path.exists() {
122 debug!("Found configuration file: {:?}", config_path);
123 break;
126 }
127 }
128
129 if workspace.config.rules.is_empty() {
131 debug!("No configuration found, using defaults");
132 }
133
134 Ok(())
135 }
136
137 pub async fn shutdown(&self) -> Result<()> {
146 info!("Shutting down OrchestrationManager");
147 debug!("OrchestrationManager shutdown complete");
148 Ok(())
149 }
150}
151
152#[cfg(test)]
153mod tests {
154 use super::*;
155 use std::path::PathBuf;
156
157 #[tokio::test]
158 async fn test_orchestration_manager_creation() {
159 let root = PathBuf::from("/test/workspace");
160 let manager = OrchestrationManager::new(root.clone());
161
162 assert_eq!(manager.workspace_root(), &root);
163 }
164
165 #[tokio::test]
166 async fn test_orchestration_manager_initialization() {
167 let root = PathBuf::from("/test/workspace");
168 let manager = OrchestrationManager::new(root.clone());
169
170 let result = manager.initialize().await;
171 assert!(result.is_ok());
172
173 let workspace = manager.get_workspace().await;
174 assert_eq!(workspace.root, root);
175 }
176
177 #[tokio::test]
178 async fn test_orchestration_manager_workspace_update() {
179 let root = PathBuf::from("/test/workspace");
180 let manager = OrchestrationManager::new(root.clone());
181
182 manager.initialize().await.expect("initialization failed");
183
184 let mut workspace = manager.get_workspace().await;
185 workspace.metrics.total_projects = 5;
186
187 manager.set_workspace(workspace.clone()).await;
188
189 let updated = manager.get_workspace().await;
190 assert_eq!(updated.metrics.total_projects, 5);
191 }
192
193 #[tokio::test]
194 async fn test_orchestration_manager_shutdown() {
195 let root = PathBuf::from("/test/workspace");
196 let manager = OrchestrationManager::new(root);
197
198 manager.initialize().await.expect("initialization failed");
199 let result = manager.shutdown().await;
200 assert!(result.is_ok());
201 }
202}