Skip to main content

peat_protocol/qos/
mod.rs

1//! Quality of Service (QoS) framework for data prioritization (ADR-019)
2//!
3//! This module provides the foundational QoS classification system for Peat Protocol,
4//! ensuring critical data (contact reports, commands) reaches commanders before routine
5//! telemetry.
6//!
7//! # Architecture
8//!
9//! - **QoSClass**: 5-level priority classification (P1 Critical → P5 Bulk)
10//! - **QoSPolicy**: Per-data-type policy with latency, TTL, retention parameters
11//! - **QoSRegistry**: Maps Peat data types to their QoS policies
12//!
13//! # Storage Management (Phase 4)
14//!
15//! - **RetentionPolicy**: Per-class retention with min/max retention times
16//! - **QoSAwareStorage**: Storage tracking with eviction candidate selection
17//! - **EvictionController**: Automated eviction with audit logging
18//! - **LifecyclePolicy**: Combined QoS + TTL (ADR-016) decision making
19//!
20//! # Example
21//!
22//! ```
23//! use peat_protocol::qos::{QoSClass, QoSPolicy, DataType, QoSRegistry};
24//!
25//! // Get default military QoS registry
26//! let registry = QoSRegistry::default_military();
27//!
28//! // Classify a contact report
29//! let class = registry.classify(DataType::ContactReport);
30//! assert_eq!(class, QoSClass::Critical);
31//!
32//! // Get full policy with latency constraints
33//! let policy = registry.get_policy(DataType::ContactReport);
34//! assert_eq!(policy.max_latency_ms, Some(500));
35//! ```
36//!
37//! # Priority Mapping
38//!
39//! | QoS Class | Description | Max Latency | Bandwidth |
40//! |-----------|-------------|-------------|-----------|
41//! | P1 Critical | Commands, Contact Reports | 500ms | 40% + preemptive |
42//! | P2 High | Mission imagery, retasking | 5s | 30% |
43//! | P3 Normal | Health status, capability changes | 60s | 20% |
44//! | P4 Low | Position updates, heartbeats | 300s | 8% |
45//! | P5 Bulk | Model updates, debug logs | None | 2% |
46//!
47//! # Storage Management Example
48//!
49//! ```
50//! use peat_protocol::qos::{
51//!     QoSClass,
52//!     storage::{QoSAwareStorage, StoredDocument},
53//!     retention::RetentionPolicies,
54//! };
55//! use std::sync::Arc;
56//!
57//! // Create storage manager with 1GB capacity
58//! let storage = Arc::new(QoSAwareStorage::new(1024 * 1024 * 1024));
59//!
60//! // Register a document
61//! storage.register_document(StoredDocument::new("doc-123", QoSClass::Normal, 1024));
62//!
63//! // Check storage pressure
64//! let pressure = storage.storage_pressure();
65//! ```
66
67// ============================================================================
68// Re-exported modules from peat-mesh (generic QoS framework)
69// ============================================================================
70
71pub mod audit;
72pub mod bandwidth;
73pub mod deletion;
74pub mod eviction;
75pub mod garbage_collection;
76pub mod lifecycle;
77pub mod preemption;
78pub mod retention;
79pub mod storage;
80pub mod sync_mode;
81
82// ============================================================================
83// Peat-specific modules (depend on military domain types)
84// ============================================================================
85
86pub mod classification;
87pub mod context;
88pub mod context_manager;
89pub mod recovery;
90pub mod registry;
91pub mod sync_queue;
92
93// ============================================================================
94// Re-export QoSClass and QoSPolicy from peat-mesh
95// ============================================================================
96
97pub use peat_mesh::qos::{QoSClass, QoSPolicy};
98
99// ============================================================================
100// Re-exports from peat-mesh QoS submodules
101// ============================================================================
102
103pub use audit::{AuditAction, AuditEntry, AuditSummary, EvictionAuditLog};
104pub use bandwidth::{
105    BandwidthAllocation, BandwidthConfig, BandwidthPermit, BandwidthQuota, QuotaConfig,
106};
107pub use deletion::{
108    DeleteResult, DeletionPolicy, DeletionPolicyRegistry, PropagationDirection, Tombstone,
109    TombstoneBatch, TombstoneDecodeError, TombstoneSyncMessage,
110};
111pub use eviction::{EvictionConfig, EvictionController, EvictionResult};
112pub use garbage_collection::{
113    start_periodic_gc, GarbageCollector, GcConfig, GcResult, GcStats, GcStore, ResurrectionPolicy,
114};
115pub use lifecycle::{
116    make_lifecycle_decision, LifecycleDecision, LifecyclePolicies, LifecyclePolicy,
117};
118pub use preemption::{ActiveTransfer, PreemptionController, PreemptionStats, TransferId};
119pub use retention::{RetentionPolicies, RetentionPolicy};
120pub use storage::{
121    ClassStorageMetrics, EvictionCandidate, QoSAwareStorage, StorageMetrics, StoredDocument,
122};
123pub use sync_mode::{SyncMode, SyncModeRegistry};
124
125// ============================================================================
126// Peat-specific re-exports
127// ============================================================================
128
129pub use classification::DataType;
130pub use context::{ContextProfile, MissionContext, QoSClassAdjustment};
131pub use context_manager::{ContextChangeListener, ContextChangeLog, ContextManager};
132pub use recovery::{RecoveryStats, SyncRecovery, UpdateBatch};
133pub use registry::QoSRegistry;
134pub use sync_queue::{PendingSync, PrioritySyncQueue, QueueStats};
135
136// ============================================================================
137// Conversions to/from existing priority types (Peat-specific)
138// ============================================================================
139
140use crate::cell::messaging::MessagePriority;
141use crate::storage::file_distribution::TransferPriority;
142
143impl From<QoSClass> for MessagePriority {
144    fn from(qos: QoSClass) -> Self {
145        match qos {
146            QoSClass::Critical => MessagePriority::Critical,
147            QoSClass::High => MessagePriority::High,
148            QoSClass::Normal => MessagePriority::Normal,
149            QoSClass::Low | QoSClass::Bulk => MessagePriority::Low,
150        }
151    }
152}
153
154impl From<MessagePriority> for QoSClass {
155    fn from(priority: MessagePriority) -> Self {
156        match priority {
157            MessagePriority::Critical => QoSClass::Critical,
158            MessagePriority::High => QoSClass::High,
159            MessagePriority::Normal => QoSClass::Normal,
160            MessagePriority::Low => QoSClass::Low,
161        }
162    }
163}
164
165impl From<QoSClass> for TransferPriority {
166    fn from(qos: QoSClass) -> Self {
167        match qos {
168            QoSClass::Critical => TransferPriority::Critical,
169            QoSClass::High => TransferPriority::High,
170            QoSClass::Normal => TransferPriority::Normal,
171            QoSClass::Low | QoSClass::Bulk => TransferPriority::Low,
172        }
173    }
174}
175
176impl From<TransferPriority> for QoSClass {
177    fn from(priority: TransferPriority) -> Self {
178        match priority {
179            TransferPriority::Critical => QoSClass::Critical,
180            TransferPriority::High => QoSClass::High,
181            TransferPriority::Normal => QoSClass::Normal,
182            TransferPriority::Low => QoSClass::Low,
183        }
184    }
185}
186
187#[cfg(test)]
188mod tests {
189    use super::*;
190
191    #[test]
192    fn test_message_priority_conversion() {
193        // QoSClass -> MessagePriority
194        assert_eq!(
195            MessagePriority::from(QoSClass::Critical),
196            MessagePriority::Critical
197        );
198        assert_eq!(MessagePriority::from(QoSClass::High), MessagePriority::High);
199        assert_eq!(
200            MessagePriority::from(QoSClass::Normal),
201            MessagePriority::Normal
202        );
203        assert_eq!(MessagePriority::from(QoSClass::Low), MessagePriority::Low);
204        assert_eq!(MessagePriority::from(QoSClass::Bulk), MessagePriority::Low);
205
206        // MessagePriority -> QoSClass
207        assert_eq!(
208            QoSClass::from(MessagePriority::Critical),
209            QoSClass::Critical
210        );
211        assert_eq!(QoSClass::from(MessagePriority::High), QoSClass::High);
212        assert_eq!(QoSClass::from(MessagePriority::Normal), QoSClass::Normal);
213        assert_eq!(QoSClass::from(MessagePriority::Low), QoSClass::Low);
214    }
215
216    #[test]
217    fn test_transfer_priority_conversion() {
218        // QoSClass -> TransferPriority
219        assert_eq!(
220            TransferPriority::from(QoSClass::Critical),
221            TransferPriority::Critical
222        );
223        assert_eq!(
224            TransferPriority::from(QoSClass::High),
225            TransferPriority::High
226        );
227        assert_eq!(
228            TransferPriority::from(QoSClass::Normal),
229            TransferPriority::Normal
230        );
231        assert_eq!(TransferPriority::from(QoSClass::Low), TransferPriority::Low);
232        assert_eq!(
233            TransferPriority::from(QoSClass::Bulk),
234            TransferPriority::Low
235        );
236
237        // TransferPriority -> QoSClass
238        assert_eq!(
239            QoSClass::from(TransferPriority::Critical),
240            QoSClass::Critical
241        );
242        assert_eq!(QoSClass::from(TransferPriority::High), QoSClass::High);
243        assert_eq!(QoSClass::from(TransferPriority::Normal), QoSClass::Normal);
244        assert_eq!(QoSClass::from(TransferPriority::Low), QoSClass::Low);
245    }
246}