Skip to main content

agentic_reality/engine/write/
topology.rs

1//! Topology write operations.
2
3use crate::engine::write::WriteEngine;
4use crate::types::error::{RealityError, RealityResult};
5use crate::types::ids::{DependencyId, NeighborId, ObserverId, ServiceId};
6use crate::types::topology::*;
7
8impl<'a> WriteEngine<'a> {
9    /// Set the agent's position in the topology.
10    pub fn set_position(&mut self, position: TopologyPosition) -> RealityResult<()> {
11        let topo =
12            self.engine
13                .topology_store
14                .topology
15                .get_or_insert_with(|| DeploymentTopologyMap {
16                    self_position: position.clone(),
17                    upstream: vec![],
18                    downstream: vec![],
19                    siblings: vec![],
20                    dependents: vec![],
21                    observers: vec![],
22                    full_graph: None,
23                    topology_health: TopologyHealth {
24                        score: 1.0,
25                        weak_links: vec![],
26                        single_points_of_failure: vec![],
27                        redundancy_score: 1.0,
28                    },
29                });
30        topo.self_position = position;
31        self.engine.mark_dirty();
32        Ok(())
33    }
34
35    /// Add an upstream entity.
36    pub fn add_upstream(&mut self, upstream: UpstreamEntity) -> RealityResult<()> {
37        let topo = self
38            .engine
39            .topology_store
40            .topology
41            .as_mut()
42            .ok_or_else(|| RealityError::NotInitialized("topology".into()))?;
43        topo.upstream.push(upstream);
44        self.engine.mark_dirty();
45        Ok(())
46    }
47
48    /// Remove an upstream entity by service ID.
49    pub fn remove_upstream(&mut self, id: &ServiceId) -> RealityResult<()> {
50        let topo = self
51            .engine
52            .topology_store
53            .topology
54            .as_mut()
55            .ok_or_else(|| RealityError::NotInitialized("topology".into()))?;
56        topo.upstream.retain(|u| u.id != *id);
57        self.engine.mark_dirty();
58        Ok(())
59    }
60
61    /// Add a downstream dependency.
62    pub fn add_downstream(&mut self, downstream: DownstreamEntity) -> RealityResult<DependencyId> {
63        let topo = self
64            .engine
65            .topology_store
66            .topology
67            .as_mut()
68            .ok_or_else(|| RealityError::NotInitialized("topology".into()))?;
69        let id = downstream.id;
70        topo.downstream.push(downstream);
71        self.engine.mark_dirty();
72        Ok(id)
73    }
74
75    /// Remove a downstream dependency.
76    pub fn remove_downstream(&mut self, id: &DependencyId) -> RealityResult<()> {
77        let topo = self
78            .engine
79            .topology_store
80            .topology
81            .as_mut()
82            .ok_or_else(|| RealityError::NotInitialized("topology".into()))?;
83        topo.downstream.retain(|d| d.id != *id);
84        self.engine.mark_dirty();
85        Ok(())
86    }
87
88    /// Update the health of a downstream dependency.
89    pub fn update_downstream_health(
90        &mut self,
91        id: &DependencyId,
92        health: HealthStatus,
93    ) -> RealityResult<()> {
94        let topo = self
95            .engine
96            .topology_store
97            .topology
98            .as_mut()
99            .ok_or_else(|| RealityError::NotInitialized("topology".into()))?;
100        let dep = topo
101            .downstream
102            .iter_mut()
103            .find(|d| d.id == *id)
104            .ok_or_else(|| RealityError::NotFound(format!("downstream {}", id)))?;
105        dep.health = health;
106        self.engine.mark_dirty();
107        Ok(())
108    }
109
110    /// Add a sibling entity.
111    pub fn add_sibling(&mut self, sibling: SiblingEntity) -> RealityResult<()> {
112        let topo = self
113            .engine
114            .topology_store
115            .topology
116            .as_mut()
117            .ok_or_else(|| RealityError::NotInitialized("topology".into()))?;
118        topo.siblings.push(sibling);
119        self.engine.mark_dirty();
120        Ok(())
121    }
122
123    /// Remove a sibling entity.
124    pub fn remove_sibling(&mut self, id: &NeighborId) -> RealityResult<()> {
125        let topo = self
126            .engine
127            .topology_store
128            .topology
129            .as_mut()
130            .ok_or_else(|| RealityError::NotInitialized("topology".into()))?;
131        topo.siblings.retain(|s| s.neighbor_id != *id);
132        self.engine.mark_dirty();
133        Ok(())
134    }
135
136    /// Update sibling state.
137    pub fn update_sibling_state(
138        &mut self,
139        id: &NeighborId,
140        health: HealthStatus,
141        load: LoadLevel,
142    ) -> RealityResult<()> {
143        let topo = self
144            .engine
145            .topology_store
146            .topology
147            .as_mut()
148            .ok_or_else(|| RealityError::NotInitialized("topology".into()))?;
149        let sib = topo
150            .siblings
151            .iter_mut()
152            .find(|s| s.neighbor_id == *id)
153            .ok_or_else(|| RealityError::NotFound(format!("sibling {}", id)))?;
154        sib.health = health;
155        sib.load = load;
156        self.engine.mark_dirty();
157        Ok(())
158    }
159
160    /// Add an observer.
161    pub fn add_observer(&mut self, observer: ObserverEntity) -> RealityResult<()> {
162        let topo = self
163            .engine
164            .topology_store
165            .topology
166            .as_mut()
167            .ok_or_else(|| RealityError::NotInitialized("topology".into()))?;
168        topo.observers.push(observer);
169        self.engine.mark_dirty();
170        Ok(())
171    }
172
173    /// Remove an observer.
174    pub fn remove_observer(&mut self, id: &ObserverId) -> RealityResult<()> {
175        let topo = self
176            .engine
177            .topology_store
178            .topology
179            .as_mut()
180            .ok_or_else(|| RealityError::NotInitialized("topology".into()))?;
181        topo.observers.retain(|o| o.id != *id);
182        self.engine.mark_dirty();
183        Ok(())
184    }
185
186    /// Update topology health.
187    pub fn update_topology_health(&mut self, health: TopologyHealth) -> RealityResult<()> {
188        let topo = self
189            .engine
190            .topology_store
191            .topology
192            .as_mut()
193            .ok_or_else(|| RealityError::NotInitialized("topology".into()))?;
194        topo.topology_health = health;
195        self.engine.mark_dirty();
196        Ok(())
197    }
198
199    /// Record a mesh event.
200    pub fn record_mesh_event(&mut self, _event: String) -> RealityResult<()> {
201        self.engine.mark_dirty();
202        Ok(())
203    }
204
205    /// Update the full topology graph.
206    pub fn update_graph(&mut self, graph: TopologyGraph) -> RealityResult<()> {
207        let topo = self
208            .engine
209            .topology_store
210            .topology
211            .as_mut()
212            .ok_or_else(|| RealityError::NotInitialized("topology".into()))?;
213        topo.full_graph = Some(graph);
214        self.engine.mark_dirty();
215        Ok(())
216    }
217}