Skip to main content

appcore_gateway/
state.rs

1// =============================================================================
2//        #######
3//     ###       ###     F: state.rs
4//    ##   ## ##   ##    P: AppCore-Runtime
5//         ## ##
6//                       C: 2026/07/26 08:53:09 by dnettoRaw
7//    ##   ## ##   ##    U: 2026/07/26 08:53:09 by dnettoRaw
8//      ###########      S: 1.0.1-rc.8
9// =============================================================================
10
11//! Shared central Gateway state.
12
13use crate::config::GatewayConfig;
14use crate::metrics::GatewayMetrics;
15use crate::tenant::TenantState;
16use crate::GatewayResult;
17use appcore_peer_rpc::{BoundedReplayStore, PeerNonceStore, ReplayStoreConfig};
18use appcore_security::HashTokenProvider;
19use appcore_types::TenantId;
20use parking_lot::RwLock;
21use std::collections::HashMap;
22use std::sync::Arc;
23use tokio::sync::watch;
24
25/// Central, thread-safe, multi-tenant state repository for the Gateway capability.
26pub struct GatewayState {
27    /// Service configuration parameters.
28    config: GatewayConfig,
29
30    /// Partitioned tenant maps containing client/worker connections and resolver tables.
31    pub tenants: RwLock<HashMap<TenantId, TenantState>>,
32
33    /// Live telemetry and performance counters.
34    pub metrics: Arc<GatewayMetrics>,
35
36    /// Token provider for cryptographic authentication checks.
37    pub token_provider: HashTokenProvider,
38
39    connection_replay: Arc<dyn PeerNonceStore>,
40    shutdown: watch::Sender<bool>,
41}
42
43impl GatewayState {
44    /// Validates configuration and instantiates the central Gateway state.
45    pub fn new(config: GatewayConfig, token_provider: HashTokenProvider) -> GatewayResult<Self> {
46        Self::with_replay_store(
47            config,
48            token_provider,
49            Arc::new(BoundedReplayStore::new(ReplayStoreConfig::default())),
50        )
51    }
52
53    /// Creates state with an explicit replay store shared by every accepted
54    /// connection for this Gateway instance.
55    pub fn with_replay_store(
56        config: GatewayConfig,
57        token_provider: HashTokenProvider,
58        connection_replay: Arc<dyn PeerNonceStore>,
59    ) -> GatewayResult<Self> {
60        config.validate()?;
61        let (shutdown, _) = watch::channel(false);
62        Ok(Self {
63            config,
64            tenants: RwLock::new(HashMap::new()),
65            metrics: GatewayMetrics::new(),
66            token_provider,
67            connection_replay,
68            shutdown,
69        })
70    }
71
72    /// Returns the validated immutable service configuration.
73    pub fn config(&self) -> &GatewayConfig {
74        &self.config
75    }
76
77    /// Requests cooperative termination of all Gateway-owned background work
78    /// and active connection loops.
79    pub fn request_shutdown(&self) {
80        self.shutdown.send_replace(true);
81    }
82
83    /// Reports whether cooperative shutdown has been requested.
84    pub fn is_shutting_down(&self) -> bool {
85        *self.shutdown.borrow()
86    }
87
88    pub(crate) fn subscribe_shutdown(&self) -> watch::Receiver<bool> {
89        self.shutdown.subscribe()
90    }
91
92    pub(crate) fn connection_replay(&self) -> &dyn PeerNonceStore {
93        self.connection_replay.as_ref()
94    }
95
96    pub(crate) async fn wait_for_shutdown(&self) {
97        let mut shutdown = self.subscribe_shutdown();
98        while !*shutdown.borrow() {
99            if shutdown.changed().await.is_err() {
100                break;
101            }
102        }
103    }
104}