agtrace_runtime/client/
monitor.rs1use crate::runtime::{SessionStreamer, WatchContext, WorkspaceEvent, WorkspaceSupervisor};
2use agtrace_index::Database;
3use anyhow::Result;
4use std::path::PathBuf;
5use std::sync::mpsc::Receiver;
6use std::sync::{Arc, Mutex};
7
8pub struct MonitorBuilder {
9 db: Arc<Mutex<Database>>,
10 provider_configs: Arc<Vec<(String, PathBuf)>>,
11 project_root: Option<PathBuf>,
12}
13
14impl MonitorBuilder {
15 pub fn new(db: Arc<Mutex<Database>>, provider_configs: Arc<Vec<(String, PathBuf)>>) -> Self {
16 Self {
17 db,
18 provider_configs,
19 project_root: None,
20 }
21 }
22
23 pub fn with_project_root(mut self, project_root: PathBuf) -> Self {
24 self.project_root = Some(project_root);
25 self
26 }
27
28 pub fn start_background_scan(self) -> Result<WorkspaceMonitor> {
29 let mut contexts = Vec::new();
30
31 for (provider_name, root) in self.provider_configs.iter() {
32 if let Ok(adapter) = agtrace_providers::create_adapter(provider_name) {
33 contexts.push(WatchContext {
34 provider_name: provider_name.clone(),
35 provider: Arc::new(adapter),
36 root: root.clone(),
37 });
38 }
39 }
40
41 let supervisor = WorkspaceSupervisor::start(contexts, self.db.clone(), self.project_root)?;
42
43 Ok(WorkspaceMonitor {
44 db: self.db,
45 supervisor,
46 provider_configs: self.provider_configs,
47 })
48 }
49}
50
51pub struct WorkspaceMonitor {
52 db: Arc<Mutex<Database>>,
53 supervisor: WorkspaceSupervisor,
54 provider_configs: Arc<Vec<(String, PathBuf)>>,
55}
56
57impl WorkspaceMonitor {
58 pub fn receiver(&self) -> &Receiver<WorkspaceEvent> {
59 self.supervisor.receiver()
60 }
61
62 pub fn next_event(&self) -> Option<WorkspaceEvent> {
63 self.supervisor.receiver().recv().ok()
64 }
65
66 pub fn attach(&self, session_id: &str, provider_name: Option<&str>) -> Result<StreamHandle> {
67 let provider_name = if let Some(name) = provider_name {
68 name.to_string()
69 } else {
70 self.provider_configs
71 .first()
72 .map(|(n, _)| n.clone())
73 .ok_or_else(|| anyhow::anyhow!("No providers available"))?
74 };
75
76 let adapter = agtrace_providers::create_adapter(&provider_name)?;
77
78 let streamer =
79 SessionStreamer::attach(session_id.to_string(), self.db.clone(), Arc::new(adapter))?;
80
81 Ok(StreamHandle { streamer })
82 }
83}
84
85pub struct StreamHandle {
86 streamer: SessionStreamer,
87}
88
89impl StreamHandle {
90 pub(crate) fn new(streamer: SessionStreamer) -> Self {
91 Self { streamer }
92 }
93
94 pub fn receiver(&self) -> &Receiver<WorkspaceEvent> {
95 self.streamer.receiver()
96 }
97}