Skip to main content

appcore_gateway/
registry.rs

1// =============================================================================
2//        #######
3//     ###       ###     F: registry.rs
4//    ##   ## ##   ##    P: AppCore-Runtime
5//         ## ##
6//                       C: 2026/07/26 08:53:09 by dnettoRaw
7//    ##   ## ##   ##    U: 2026/08/02 12:48:56 by dnettoRaw
8//      ###########      S: 1.0.1-rc.8
9// =============================================================================
10
11//! Capability advertisement registry.
12
13use crate::connection::WorkerConnectionKey;
14use appcore_types::CapabilityName;
15use std::collections::{HashMap, HashSet};
16
17/// Tracks which workers advertise which capabilities within a tenant partition.
18#[derive(Debug, Default, Clone)]
19pub struct CapabilityRegistry {
20    capability_to_workers: HashMap<CapabilityName, HashSet<WorkerConnectionKey>>,
21    worker_to_capabilities: HashMap<WorkerConnectionKey, HashSet<CapabilityName>>,
22}
23
24impl CapabilityRegistry {
25    /// Creates an empty capability registry.
26    pub fn new() -> Self {
27        Self::default()
28    }
29
30    /// Registers capabilities for a specific worker.
31    pub fn register(&mut self, worker: WorkerConnectionKey, capabilities: Vec<CapabilityName>) {
32        self.deregister(&worker);
33        let mut caps_set = HashSet::new();
34        for cap in capabilities {
35            self.capability_to_workers
36                .entry(cap.clone())
37                .or_default()
38                .insert(worker.clone());
39            caps_set.insert(cap);
40        }
41        self.worker_to_capabilities.insert(worker, caps_set);
42    }
43
44    /// Deregisters all capabilities associated with a specific worker connection.
45    pub fn deregister(&mut self, worker: &WorkerConnectionKey) {
46        if let Some(caps) = self.worker_to_capabilities.remove(worker) {
47            for cap in caps {
48                if let Some(workers) = self.capability_to_workers.get_mut(&cap) {
49                    workers.remove(worker);
50                    if workers.is_empty() {
51                        self.capability_to_workers.remove(&cap);
52                    }
53                }
54            }
55        }
56    }
57
58    /// Returns all workers advertising a specific capability.
59    pub fn resolve(&self, capability: &CapabilityName) -> Option<&HashSet<WorkerConnectionKey>> {
60        self.capability_to_workers.get(capability)
61    }
62
63    /// Returns all capabilities currently advertised by any worker.
64    pub fn all_capabilities(&self) -> Vec<CapabilityName> {
65        self.capability_to_workers.keys().cloned().collect()
66    }
67}