1use anyhow::{anyhow, Result};
8use serde::Serialize;
9use std::collections::{HashMap, HashSet, VecDeque};
10use std::sync::Arc;
11use std::time::{Duration, Instant, SystemTime};
12use tokio::sync::{broadcast, mpsc, Mutex as AsyncMutex, RwLock};
13use tokio_stream::StreamExt;
14use tracing::{error, info, warn};
15
16use crate::ast::{Document, Value};
17use crate::performance::ClientInfo;
18
19#[derive(Debug, Clone)]
21pub struct AdvancedSubscriptionConfig {
22 pub enable_intelligent_multiplexing: bool,
23 pub enable_real_time_filtering: bool,
24 pub enable_data_transformation: bool,
25 pub enable_subscription_batching: bool,
26 pub enable_priority_queuing: bool,
27 pub enable_backpressure_control: bool,
28 pub max_concurrent_subscriptions: usize,
29 pub subscription_timeout: Duration,
30 pub batch_size: usize,
31 pub batch_timeout: Duration,
32 pub heartbeat_interval: Duration,
33 pub buffer_size: usize,
34 pub compression_threshold: usize,
35}
36
37impl Default for AdvancedSubscriptionConfig {
38 fn default() -> Self {
39 Self {
40 enable_intelligent_multiplexing: true,
41 enable_real_time_filtering: true,
42 enable_data_transformation: true,
43 enable_subscription_batching: true,
44 enable_priority_queuing: true,
45 enable_backpressure_control: true,
46 max_concurrent_subscriptions: 10000,
47 subscription_timeout: Duration::from_secs(300), batch_size: 100,
49 batch_timeout: Duration::from_millis(50),
50 heartbeat_interval: Duration::from_secs(30),
51 buffer_size: 1000,
52 compression_threshold: 1024, }
54 }
55}
56
57pub struct AdvancedSubscriptionManager {
59 config: AdvancedSubscriptionConfig,
60 active_subscriptions: Arc<RwLock<HashMap<String, SubscriptionSession>>>,
61 subscription_groups: Arc<RwLock<HashMap<String, SubscriptionGroup>>>,
62 event_multiplexer: Arc<EventMultiplexer>,
63 data_transformer: Arc<DataTransformer>,
64 #[allow(dead_code)]
65 priority_queue: Arc<AsyncMutex<PriorityQueue>>,
66 metrics: Arc<RwLock<SubscriptionMetrics>>,
67 event_source: broadcast::Sender<RealTimeEvent>,
68 #[allow(dead_code)]
69 event_receiver: broadcast::Receiver<RealTimeEvent>,
70}
71
72impl AdvancedSubscriptionManager {
73 pub fn new(config: AdvancedSubscriptionConfig) -> Self {
74 let (event_source, event_receiver) = broadcast::channel(10000);
75
76 Self {
77 config: config.clone(),
78 active_subscriptions: Arc::new(RwLock::new(HashMap::new())),
79 subscription_groups: Arc::new(RwLock::new(HashMap::new())),
80 event_multiplexer: Arc::new(EventMultiplexer::new(&config)),
81 data_transformer: Arc::new(DataTransformer::new()),
82 priority_queue: Arc::new(AsyncMutex::new(PriorityQueue::new())),
83 metrics: Arc::new(RwLock::new(SubscriptionMetrics::new())),
84 event_source,
85 event_receiver,
86 }
87 }
88
89 pub async fn create_subscription(
91 &self,
92 subscription_id: String,
93 document: Document,
94 variables: HashMap<String, Value>,
95 client_info: ClientInfo,
96 priority: SubscriptionPriority,
97 ) -> Result<SubscriptionStream> {
98 let current_count = self.active_subscriptions.read().await.len();
100 if current_count >= self.config.max_concurrent_subscriptions {
101 return Err(anyhow!("Maximum subscription limit reached"));
102 }
103
104 let analysis = self.analyze_subscription(&document).await?;
106
107 let session = SubscriptionSession {
109 id: subscription_id.clone(),
110 document: document.clone(),
111 variables,
112 client_info,
113 priority,
114 analysis,
115 created_at: SystemTime::now(),
116 last_activity: SystemTime::now(),
117 message_count: 0,
118 bytes_sent: 0,
119 filters: self.extract_filters(&document)?,
120 transformations: self.extract_transformations(&document)?,
121 };
122
123 if self.config.enable_intelligent_multiplexing {
125 self.event_multiplexer
126 .register_subscription(&session)
127 .await?;
128 }
129
130 let group_key = self.calculate_group_key(&session);
132 self.add_to_subscription_group(&group_key, &session).await?;
133
134 let stream = self.create_subscription_stream(&session).await?;
136
137 self.active_subscriptions
139 .write()
140 .await
141 .insert(subscription_id.clone(), session);
142
143 self.metrics.write().await.subscription_created();
145
146 info!(
147 "Created advanced subscription: {} with priority {:?}",
148 subscription_id, priority
149 );
150
151 Ok(stream)
152 }
153
154 async fn analyze_subscription(&self, document: &Document) -> Result<SubscriptionAnalysis> {
156 let complexity = self.calculate_subscription_complexity(document)?;
157 let data_requirements = self.analyze_data_requirements(document)?;
158 let update_frequency = self.estimate_update_frequency(document)?;
159 let resource_usage = self.estimate_resource_usage(document, complexity)?;
160
161 Ok(SubscriptionAnalysis {
162 complexity,
163 data_requirements,
164 update_frequency,
165 resource_usage,
166 can_batch: self.can_batch_subscription(document),
167 can_multiplex: self.can_multiplex_subscription(document),
168 cacheable_fields: self.identify_cacheable_fields(document),
169 })
170 }
171
172 async fn create_subscription_stream(
174 &self,
175 session: &SubscriptionSession,
176 ) -> Result<SubscriptionStream> {
177 let (tx, rx) = mpsc::channel(self.config.buffer_size);
178
179 let processor = StreamProcessor::new(
181 session.clone(),
182 self.config.clone(),
183 self.data_transformer.clone(),
184 );
185
186 let event_rx = self.event_source.subscribe();
188 let subscription_id = session.id.clone();
189 let filters = session.filters.clone();
190 let transformations = session.transformations.clone();
191 let processor_clone = processor.clone();
192
193 tokio::spawn(async move {
195 let mut event_stream = tokio_stream::wrappers::BroadcastStream::new(event_rx);
196
197 while let Some(event_result) = event_stream.next().await {
198 match event_result {
199 Ok(event) => {
200 if processor_clone.should_process_event(&event, &filters).await {
202 match processor_clone
204 .transform_event(event, &transformations)
205 .await
206 {
207 Ok(transformed_event) => {
208 if let Err(e) = tx.send(transformed_event).await {
209 warn!(
210 "Failed to send event to subscription {}: {}",
211 subscription_id, e
212 );
213 break;
214 }
215 }
216 Err(e) => {
217 error!(
218 "Failed to transform event for subscription {}: {}",
219 subscription_id, e
220 );
221 }
222 }
223 }
224 }
225 Err(e) => {
226 error!(
227 "Error receiving event for subscription {}: {}",
228 subscription_id, e
229 );
230 break;
231 }
232 }
233 }
234 });
235
236 Ok(SubscriptionStream {
237 id: session.id.clone(),
238 receiver: rx,
239 processor,
240 created_at: Instant::now(),
241 message_count: 0,
242 })
243 }
244
245 pub async fn publish_event(&self, event: RealTimeEvent) -> Result<PublishResult> {
247 let start_time = Instant::now();
248
249 let targeted_subscriptions = if self.config.enable_intelligent_multiplexing {
251 self.event_multiplexer
252 .find_interested_subscriptions(&event)
253 .await?
254 } else {
255 self.get_all_subscription_ids().await
256 };
257
258 let subscriber_count = self
260 .event_source
261 .send(event.clone())
262 .map_err(|_| anyhow!("Failed to broadcast event"))?;
263
264 let mut metrics = self.metrics.write().await;
266 metrics.event_published(targeted_subscriptions.len(), start_time.elapsed());
267
268 info!(
269 "Published event to {} subscribers in {:?}",
270 subscriber_count,
271 start_time.elapsed()
272 );
273
274 Ok(PublishResult {
275 event_id: event.id,
276 subscriber_count,
277 targeted_subscriptions,
278 processing_time: start_time.elapsed(),
279 })
280 }
281
282 pub async fn cancel_subscription(&self, subscription_id: &str) -> Result<()> {
284 let session = self
286 .active_subscriptions
287 .write()
288 .await
289 .remove(subscription_id);
290
291 if let Some(session) = session {
292 if self.config.enable_intelligent_multiplexing {
294 self.event_multiplexer
295 .unregister_subscription(&session)
296 .await?;
297 }
298
299 let group_key = self.calculate_group_key(&session);
301 self.remove_from_subscription_group(&group_key, subscription_id)
302 .await?;
303
304 self.metrics.write().await.subscription_cancelled();
306
307 info!("Cancelled subscription: {}", subscription_id);
308 Ok(())
309 } else {
310 Err(anyhow!("Subscription not found: {}", subscription_id))
311 }
312 }
313
314 pub async fn get_analytics(&self) -> SubscriptionAnalytics {
316 let subscriptions = self.active_subscriptions.read().await;
317 let groups = self.subscription_groups.read().await;
318 let metrics = self.metrics.read().await;
319 let multiplexer_stats = self.event_multiplexer.get_statistics().await;
320
321 SubscriptionAnalytics {
322 total_subscriptions: subscriptions.len(),
323 subscription_groups: groups.len(),
324 average_group_size: if groups.is_empty() {
325 0.0
326 } else {
327 subscriptions.len() as f64 / groups.len() as f64
328 },
329 events_per_second: metrics.events_per_second(),
330 average_processing_time: metrics.average_processing_time(),
331 memory_usage_mb: self.estimate_memory_usage(&subscriptions),
332 multiplexer_efficiency: multiplexer_stats.efficiency_ratio,
333 subscription_distribution: self.calculate_subscription_distribution(&subscriptions),
334 performance_metrics: metrics.clone(),
335 }
336 }
337
338 fn calculate_subscription_complexity(&self, _document: &Document) -> Result<f64> {
341 Ok(5.0) }
344
345 fn analyze_data_requirements(&self, _document: &Document) -> Result<DataRequirements> {
346 Ok(DataRequirements {
347 entities: vec!["User".to_string(), "Post".to_string()],
348 relationships: vec![("User".to_string(), "Posts".to_string())],
349 update_patterns: vec![UpdatePattern::RealTime, UpdatePattern::Batched],
350 })
351 }
352
353 fn estimate_update_frequency(&self, _document: &Document) -> Result<Duration> {
354 Ok(Duration::from_secs(1)) }
356
357 fn estimate_resource_usage(
358 &self,
359 _document: &Document,
360 complexity: f64,
361 ) -> Result<ResourceUsage> {
362 Ok(ResourceUsage {
363 memory_mb: complexity * 0.1,
364 cpu_percent: complexity * 0.05,
365 network_bandwidth_kbps: complexity * 10.0,
366 })
367 }
368
369 fn can_batch_subscription(&self, _document: &Document) -> bool {
370 true }
372
373 fn can_multiplex_subscription(&self, _document: &Document) -> bool {
374 true }
376
377 fn identify_cacheable_fields(&self, _document: &Document) -> Vec<String> {
378 vec!["user".to_string(), "metadata".to_string()] }
380
381 fn extract_filters(&self, _document: &Document) -> Result<Vec<SubscriptionFilter>> {
382 Ok(vec![SubscriptionFilter {
383 field_path: "user.id".to_string(),
384 operator: FilterOperator::Equals,
385 value: Value::StringValue("user123".to_string()),
386 }])
387 }
388
389 fn extract_transformations(&self, _document: &Document) -> Result<Vec<DataTransformation>> {
390 Ok(vec![DataTransformation {
391 transformation_type: TransformationType::FieldMapping,
392 source_field: "userId".to_string(),
393 target_field: "user.id".to_string(),
394 parameters: HashMap::new(),
395 }])
396 }
397
398 fn calculate_group_key(&self, session: &SubscriptionSession) -> String {
399 format!(
401 "group_{}_{}",
402 session.analysis.data_requirements.entities.join("_"),
403 session.priority as u8
404 )
405 }
406
407 async fn add_to_subscription_group(
408 &self,
409 group_key: &str,
410 session: &SubscriptionSession,
411 ) -> Result<()> {
412 let mut groups = self.subscription_groups.write().await;
413 let group = groups
414 .entry(group_key.to_string())
415 .or_insert_with(|| SubscriptionGroup::new(group_key.to_string()));
416 group.add_subscription(session.id.clone());
417 Ok(())
418 }
419
420 async fn remove_from_subscription_group(
421 &self,
422 group_key: &str,
423 subscription_id: &str,
424 ) -> Result<()> {
425 let mut groups = self.subscription_groups.write().await;
426 if let Some(group) = groups.get_mut(group_key) {
427 group.remove_subscription(subscription_id);
428 if group.is_empty() {
429 groups.remove(group_key);
430 }
431 }
432 Ok(())
433 }
434
435 async fn get_all_subscription_ids(&self) -> Vec<String> {
436 self.active_subscriptions
437 .read()
438 .await
439 .keys()
440 .cloned()
441 .collect()
442 }
443
444 fn estimate_memory_usage(&self, subscriptions: &HashMap<String, SubscriptionSession>) -> f64 {
445 subscriptions
446 .values()
447 .map(|s| s.analysis.resource_usage.memory_mb)
448 .sum()
449 }
450
451 fn calculate_subscription_distribution(
452 &self,
453 subscriptions: &HashMap<String, SubscriptionSession>,
454 ) -> HashMap<String, usize> {
455 let mut distribution = HashMap::new();
456
457 for session in subscriptions.values() {
458 let priority_key = format!("{:?}", session.priority);
459 *distribution.entry(priority_key).or_insert(0) += 1;
460 }
461
462 distribution
463 }
464}
465
466pub struct EventMultiplexer {
468 #[allow(dead_code)]
469 config: AdvancedSubscriptionConfig,
470 subscription_index: Arc<RwLock<SubscriptionIndex>>,
471 statistics: Arc<RwLock<MultiplexerStatistics>>,
472}
473
474impl EventMultiplexer {
475 pub fn new(config: &AdvancedSubscriptionConfig) -> Self {
476 Self {
477 config: config.clone(),
478 subscription_index: Arc::new(RwLock::new(SubscriptionIndex::new())),
479 statistics: Arc::new(RwLock::new(MultiplexerStatistics::new())),
480 }
481 }
482
483 pub async fn register_subscription(&self, session: &SubscriptionSession) -> Result<()> {
484 let mut index = self.subscription_index.write().await;
485 index.add_subscription(session);
486
487 let mut stats = self.statistics.write().await;
488 stats.subscriptions_registered += 1;
489
490 Ok(())
491 }
492
493 pub async fn unregister_subscription(&self, session: &SubscriptionSession) -> Result<()> {
494 let mut index = self.subscription_index.write().await;
495 index.remove_subscription(&session.id);
496
497 let mut stats = self.statistics.write().await;
498 stats.subscriptions_unregistered += 1;
499
500 Ok(())
501 }
502
503 pub async fn find_interested_subscriptions(
504 &self,
505 event: &RealTimeEvent,
506 ) -> Result<Vec<String>> {
507 let index = self.subscription_index.read().await;
508 let interested = index.find_matching_subscriptions(event);
509
510 let mut stats = self.statistics.write().await;
511 stats.events_processed += 1;
512 stats.total_subscription_checks += index.total_subscriptions();
513 stats.matched_subscriptions += interested.len();
514
515 Ok(interested)
516 }
517
518 pub async fn get_statistics(&self) -> MultiplexerStatistics {
519 self.statistics.read().await.clone()
520 }
521}
522
523#[derive(Debug, Clone)]
525pub struct DataTransformer {
526 #[allow(dead_code)]
527 transform_cache: Arc<RwLock<HashMap<String, TransformationResult>>>,
528}
529
530impl Default for DataTransformer {
531 fn default() -> Self {
532 Self::new()
533 }
534}
535
536impl DataTransformer {
537 pub fn new() -> Self {
538 Self {
539 transform_cache: Arc::new(RwLock::new(HashMap::new())),
540 }
541 }
542
543 pub async fn transform_data(
544 &self,
545 data: Value,
546 transformations: &[DataTransformation],
547 ) -> Result<Value> {
548 let mut result = data;
549
550 for transformation in transformations {
551 result = self.apply_transformation(result, transformation).await?;
552 }
553
554 Ok(result)
555 }
556
557 async fn apply_transformation(
558 &self,
559 data: Value,
560 transformation: &DataTransformation,
561 ) -> Result<Value> {
562 match transformation.transformation_type {
563 TransformationType::FieldMapping => {
564 Ok(data)
566 }
567 TransformationType::DataFiltering => {
568 Ok(data)
570 }
571 TransformationType::Aggregation => {
572 Ok(data)
574 }
575 TransformationType::Normalization => {
576 Ok(data)
578 }
579 }
580 }
581}
582
583#[derive(Debug, Clone)]
585#[allow(dead_code)]
586pub struct StreamProcessor {
587 session: SubscriptionSession,
588 config: AdvancedSubscriptionConfig,
589 data_transformer: Arc<DataTransformer>,
590 last_heartbeat: Arc<AsyncMutex<Instant>>,
591}
592
593impl StreamProcessor {
594 pub fn new(
595 session: SubscriptionSession,
596 config: AdvancedSubscriptionConfig,
597 data_transformer: Arc<DataTransformer>,
598 ) -> Self {
599 Self {
600 session,
601 config,
602 data_transformer,
603 last_heartbeat: Arc::new(AsyncMutex::new(Instant::now())),
604 }
605 }
606
607 pub async fn should_process_event(
608 &self,
609 event: &RealTimeEvent,
610 filters: &[SubscriptionFilter],
611 ) -> bool {
612 for filter in filters {
614 if !self.evaluate_filter(event, filter) {
615 return false;
616 }
617 }
618 true
619 }
620
621 pub async fn transform_event(
622 &self,
623 event: RealTimeEvent,
624 transformations: &[DataTransformation],
625 ) -> Result<SubscriptionMessage> {
626 let transformed_data = self
627 .data_transformer
628 .transform_data(event.data.clone(), transformations)
629 .await?;
630
631 Ok(SubscriptionMessage {
632 subscription_id: self.session.id.clone(),
633 event_id: event.id,
634 data: transformed_data,
635 timestamp: SystemTime::now(),
636 sequence_number: event.sequence_number,
637 })
638 }
639
640 fn evaluate_filter(&self, _event: &RealTimeEvent, filter: &SubscriptionFilter) -> bool {
641 match &filter.operator {
643 FilterOperator::Equals => {
644 true }
647 FilterOperator::NotEquals => true,
648 FilterOperator::GreaterThan => true,
649 FilterOperator::LessThan => true,
650 FilterOperator::Contains => true,
651 FilterOperator::StartsWith => true,
652 FilterOperator::EndsWith => true,
653 }
654 }
655}
656
657pub struct PriorityQueue {
659 high_priority: VecDeque<String>,
660 normal_priority: VecDeque<String>,
661 low_priority: VecDeque<String>,
662}
663
664impl Default for PriorityQueue {
665 fn default() -> Self {
666 Self::new()
667 }
668}
669
670impl PriorityQueue {
671 pub fn new() -> Self {
672 Self {
673 high_priority: VecDeque::new(),
674 normal_priority: VecDeque::new(),
675 low_priority: VecDeque::new(),
676 }
677 }
678
679 pub fn enqueue(&mut self, subscription_id: String, priority: SubscriptionPriority) {
680 match priority {
681 SubscriptionPriority::High => self.high_priority.push_back(subscription_id),
682 SubscriptionPriority::Normal => self.normal_priority.push_back(subscription_id),
683 SubscriptionPriority::Low => self.low_priority.push_back(subscription_id),
684 }
685 }
686
687 pub fn dequeue(&mut self) -> Option<String> {
688 self.high_priority
689 .pop_front()
690 .or_else(|| self.normal_priority.pop_front())
691 .or_else(|| self.low_priority.pop_front())
692 }
693
694 pub fn len(&self) -> usize {
695 self.high_priority.len() + self.normal_priority.len() + self.low_priority.len()
696 }
697
698 pub fn is_empty(&self) -> bool {
699 self.len() == 0
700 }
701}
702
703#[derive(Debug, Clone)]
706pub struct SubscriptionSession {
707 pub id: String,
708 pub document: Document,
709 pub variables: HashMap<String, Value>,
710 pub client_info: ClientInfo,
711 pub priority: SubscriptionPriority,
712 pub analysis: SubscriptionAnalysis,
713 pub created_at: SystemTime,
714 pub last_activity: SystemTime,
715 pub message_count: u64,
716 pub bytes_sent: u64,
717 pub filters: Vec<SubscriptionFilter>,
718 pub transformations: Vec<DataTransformation>,
719}
720
721#[derive(Debug, Clone)]
722pub struct SubscriptionAnalysis {
723 pub complexity: f64,
724 pub data_requirements: DataRequirements,
725 pub update_frequency: Duration,
726 pub resource_usage: ResourceUsage,
727 pub can_batch: bool,
728 pub can_multiplex: bool,
729 pub cacheable_fields: Vec<String>,
730}
731
732#[derive(Debug, Clone)]
733pub struct DataRequirements {
734 pub entities: Vec<String>,
735 pub relationships: Vec<(String, String)>,
736 pub update_patterns: Vec<UpdatePattern>,
737}
738
739#[derive(Debug, Clone)]
740pub enum UpdatePattern {
741 RealTime,
742 Batched,
743 Periodic,
744 EventDriven,
745}
746
747#[derive(Debug, Clone)]
748pub struct ResourceUsage {
749 pub memory_mb: f64,
750 pub cpu_percent: f64,
751 pub network_bandwidth_kbps: f64,
752}
753
754#[derive(Debug, Clone, Copy, Eq, Hash, PartialEq)]
755pub enum SubscriptionPriority {
756 High = 3,
757 Normal = 2,
758 Low = 1,
759}
760
761#[derive(Debug, Clone, Serialize)]
762pub struct RealTimeEvent {
763 pub id: String,
764 pub event_type: String,
765 pub data: Value,
766 pub timestamp: SystemTime,
767 pub sequence_number: u64,
768 pub source: String,
769 pub metadata: HashMap<String, String>,
770}
771
772#[derive(Debug, Clone)]
773pub struct SubscriptionFilter {
774 pub field_path: String,
775 pub operator: FilterOperator,
776 pub value: Value,
777}
778
779#[derive(Debug, Clone)]
780pub enum FilterOperator {
781 Equals,
782 NotEquals,
783 GreaterThan,
784 LessThan,
785 Contains,
786 StartsWith,
787 EndsWith,
788}
789
790#[derive(Debug, Clone)]
791pub struct DataTransformation {
792 pub transformation_type: TransformationType,
793 pub source_field: String,
794 pub target_field: String,
795 pub parameters: HashMap<String, String>,
796}
797
798#[derive(Debug, Clone)]
799pub enum TransformationType {
800 FieldMapping,
801 DataFiltering,
802 Aggregation,
803 Normalization,
804}
805
806#[derive(Debug)]
807pub struct SubscriptionStream {
808 pub id: String,
809 pub receiver: mpsc::Receiver<SubscriptionMessage>,
810 pub processor: StreamProcessor,
811 pub created_at: Instant,
812 pub message_count: u64,
813}
814
815#[derive(Debug, Clone, Serialize)]
816pub struct SubscriptionMessage {
817 pub subscription_id: String,
818 pub event_id: String,
819 pub data: Value,
820 pub timestamp: SystemTime,
821 pub sequence_number: u64,
822}
823
824#[derive(Debug, Clone)]
825pub struct SubscriptionGroup {
826 pub id: String,
827 pub subscription_ids: HashSet<String>,
828 pub created_at: SystemTime,
829}
830
831impl SubscriptionGroup {
832 pub fn new(id: String) -> Self {
833 Self {
834 id,
835 subscription_ids: HashSet::new(),
836 created_at: SystemTime::now(),
837 }
838 }
839
840 pub fn add_subscription(&mut self, subscription_id: String) {
841 self.subscription_ids.insert(subscription_id);
842 }
843
844 pub fn remove_subscription(&mut self, subscription_id: &str) {
845 self.subscription_ids.remove(subscription_id);
846 }
847
848 pub fn is_empty(&self) -> bool {
849 self.subscription_ids.is_empty()
850 }
851}
852
853#[derive(Debug, Clone)]
854pub struct SubscriptionIndex {
855 by_entity: HashMap<String, HashSet<String>>,
856 by_priority: HashMap<SubscriptionPriority, HashSet<String>>,
857 by_event_type: HashMap<String, HashSet<String>>,
858}
859
860impl Default for SubscriptionIndex {
861 fn default() -> Self {
862 Self::new()
863 }
864}
865
866impl SubscriptionIndex {
867 pub fn new() -> Self {
868 Self {
869 by_entity: HashMap::new(),
870 by_priority: HashMap::new(),
871 by_event_type: HashMap::new(),
872 }
873 }
874
875 pub fn add_subscription(&mut self, session: &SubscriptionSession) {
876 for entity in &session.analysis.data_requirements.entities {
878 self.by_entity
879 .entry(entity.clone())
880 .or_default()
881 .insert(session.id.clone());
882 }
883
884 self.by_priority
886 .entry(session.priority)
887 .or_default()
888 .insert(session.id.clone());
889
890 self.by_event_type
892 .entry("data_change".to_string())
893 .or_default()
894 .insert(session.id.clone());
895 }
896
897 pub fn remove_subscription(&mut self, subscription_id: &str) {
898 for subscriptions in self.by_entity.values_mut() {
900 subscriptions.remove(subscription_id);
901 }
902 for subscriptions in self.by_priority.values_mut() {
903 subscriptions.remove(subscription_id);
904 }
905 for subscriptions in self.by_event_type.values_mut() {
906 subscriptions.remove(subscription_id);
907 }
908 }
909
910 pub fn find_matching_subscriptions(&self, event: &RealTimeEvent) -> Vec<String> {
911 self.by_event_type
913 .get(&event.event_type)
914 .cloned()
915 .unwrap_or_default()
916 .into_iter()
917 .collect()
918 }
919
920 pub fn total_subscriptions(&self) -> usize {
921 self.by_event_type.values().map(|set| set.len()).sum()
922 }
923}
924
925#[derive(Debug, Clone)]
926pub struct MultiplexerStatistics {
927 pub subscriptions_registered: u64,
928 pub subscriptions_unregistered: u64,
929 pub events_processed: u64,
930 pub total_subscription_checks: usize,
931 pub matched_subscriptions: usize,
932 pub efficiency_ratio: f64,
933}
934
935impl Default for MultiplexerStatistics {
936 fn default() -> Self {
937 Self::new()
938 }
939}
940
941impl MultiplexerStatistics {
942 pub fn new() -> Self {
943 Self {
944 subscriptions_registered: 0,
945 subscriptions_unregistered: 0,
946 events_processed: 0,
947 total_subscription_checks: 0,
948 matched_subscriptions: 0,
949 efficiency_ratio: 0.0,
950 }
951 }
952}
953
954#[derive(Debug, Clone)]
955pub struct SubscriptionMetrics {
956 pub total_subscriptions_created: u64,
957 pub total_subscriptions_cancelled: u64,
958 pub total_events_published: u64,
959 pub total_messages_sent: u64,
960 pub total_processing_time: Duration,
961 pub last_event_time: Option<Instant>,
962}
963
964impl Default for SubscriptionMetrics {
965 fn default() -> Self {
966 Self::new()
967 }
968}
969
970impl SubscriptionMetrics {
971 pub fn new() -> Self {
972 Self {
973 total_subscriptions_created: 0,
974 total_subscriptions_cancelled: 0,
975 total_events_published: 0,
976 total_messages_sent: 0,
977 total_processing_time: Duration::from_millis(0),
978 last_event_time: None,
979 }
980 }
981
982 pub fn subscription_created(&mut self) {
983 self.total_subscriptions_created += 1;
984 }
985
986 pub fn subscription_cancelled(&mut self) {
987 self.total_subscriptions_cancelled += 1;
988 }
989
990 pub fn event_published(&mut self, subscriber_count: usize, processing_time: Duration) {
991 self.total_events_published += 1;
992 self.total_messages_sent += subscriber_count as u64;
993 self.total_processing_time += processing_time;
994 self.last_event_time = Some(Instant::now());
995 }
996
997 pub fn events_per_second(&self) -> f64 {
998 if let Some(last_time) = self.last_event_time {
999 let duration = last_time.elapsed().as_secs_f64();
1000 if duration > 0.0 {
1001 self.total_events_published as f64 / duration
1002 } else {
1003 0.0
1004 }
1005 } else {
1006 0.0
1007 }
1008 }
1009
1010 pub fn average_processing_time(&self) -> Duration {
1011 if self.total_events_published > 0 {
1012 self.total_processing_time / self.total_events_published as u32
1013 } else {
1014 Duration::from_millis(0)
1015 }
1016 }
1017}
1018
1019#[derive(Debug, Clone)]
1020pub struct PublishResult {
1021 pub event_id: String,
1022 pub subscriber_count: usize,
1023 pub targeted_subscriptions: Vec<String>,
1024 pub processing_time: Duration,
1025}
1026
1027#[derive(Debug, Clone)]
1028pub struct SubscriptionAnalytics {
1029 pub total_subscriptions: usize,
1030 pub subscription_groups: usize,
1031 pub average_group_size: f64,
1032 pub events_per_second: f64,
1033 pub average_processing_time: Duration,
1034 pub memory_usage_mb: f64,
1035 pub multiplexer_efficiency: f64,
1036 pub subscription_distribution: HashMap<String, usize>,
1037 pub performance_metrics: SubscriptionMetrics,
1038}
1039
1040#[derive(Debug, Clone)]
1041pub struct TransformationResult {
1042 pub original_data: Value,
1043 pub transformed_data: Value,
1044 pub transformation_time: Duration,
1045 pub cache_key: String,
1046}
1047
1048#[cfg(test)]
1049mod tests {
1050 use super::*;
1051 use crate::ast::{Definition, OperationDefinition, OperationType, SelectionSet};
1052
1053 #[tokio::test]
1054 async fn test_subscription_manager_creation() {
1055 let config = AdvancedSubscriptionConfig::default();
1056 let manager = AdvancedSubscriptionManager::new(config);
1057
1058 let analytics = manager.get_analytics().await;
1059 assert_eq!(analytics.total_subscriptions, 0);
1060 }
1061
1062 #[tokio::test]
1063 async fn test_subscription_creation() {
1064 let config = AdvancedSubscriptionConfig::default();
1065 let manager = AdvancedSubscriptionManager::new(config);
1066
1067 let document = Document {
1068 definitions: vec![Definition::Operation(OperationDefinition {
1069 operation_type: OperationType::Subscription,
1070 name: Some("TestSubscription".to_string()),
1071 variable_definitions: vec![],
1072 directives: vec![],
1073 selection_set: SelectionSet { selections: vec![] },
1074 })],
1075 };
1076
1077 let result = manager
1078 .create_subscription(
1079 "test_sub_1".to_string(),
1080 document,
1081 HashMap::new(),
1082 ClientInfo::default(),
1083 SubscriptionPriority::Normal,
1084 )
1085 .await;
1086
1087 assert!(result.is_ok());
1088
1089 let analytics = manager.get_analytics().await;
1090 assert_eq!(analytics.total_subscriptions, 1);
1091 }
1092
1093 #[tokio::test]
1094 async fn test_event_publishing() {
1095 let config = AdvancedSubscriptionConfig::default();
1096 let manager = AdvancedSubscriptionManager::new(config);
1097
1098 let event = RealTimeEvent {
1099 id: "event_1".to_string(),
1100 event_type: "data_change".to_string(),
1101 data: Value::StringValue("test_data".to_string()),
1102 timestamp: SystemTime::now(),
1103 sequence_number: 1,
1104 source: "test_source".to_string(),
1105 metadata: HashMap::new(),
1106 };
1107
1108 let result = manager.publish_event(event).await;
1109 assert!(result.is_ok());
1110 }
1111
1112 #[tokio::test]
1113 async fn test_priority_queue() {
1114 let mut queue = PriorityQueue::new();
1115
1116 queue.enqueue("low".to_string(), SubscriptionPriority::Low);
1117 queue.enqueue("high".to_string(), SubscriptionPriority::High);
1118 queue.enqueue("normal".to_string(), SubscriptionPriority::Normal);
1119
1120 assert_eq!(queue.dequeue(), Some("high".to_string()));
1121 assert_eq!(queue.dequeue(), Some("normal".to_string()));
1122 assert_eq!(queue.dequeue(), Some("low".to_string()));
1123 }
1124
1125 #[tokio::test]
1126 async fn test_subscription_index() {
1127 let mut index = SubscriptionIndex::new();
1128
1129 let session = SubscriptionSession {
1130 id: "test_sub".to_string(),
1131 document: Document {
1132 definitions: vec![],
1133 },
1134 variables: HashMap::new(),
1135 client_info: ClientInfo::default(),
1136 priority: SubscriptionPriority::Normal,
1137 analysis: SubscriptionAnalysis {
1138 complexity: 1.0,
1139 data_requirements: DataRequirements {
1140 entities: vec!["User".to_string()],
1141 relationships: vec![],
1142 update_patterns: vec![],
1143 },
1144 update_frequency: Duration::from_secs(1),
1145 resource_usage: ResourceUsage {
1146 memory_mb: 1.0,
1147 cpu_percent: 1.0,
1148 network_bandwidth_kbps: 10.0,
1149 },
1150 can_batch: true,
1151 can_multiplex: true,
1152 cacheable_fields: vec![],
1153 },
1154 created_at: SystemTime::now(),
1155 last_activity: SystemTime::now(),
1156 message_count: 0,
1157 bytes_sent: 0,
1158 filters: vec![],
1159 transformations: vec![],
1160 };
1161
1162 index.add_subscription(&session);
1163 assert_eq!(index.total_subscriptions(), 1);
1164
1165 index.remove_subscription("test_sub");
1166 assert_eq!(index.total_subscriptions(), 0);
1167 }
1168}