p2p_chat/sync/engine/mailbox/
reliability.rs1use std::time::{Duration, Instant};
4
5use libp2p::PeerId;
6use tracing::{error, warn};
7
8use super::super::performance::MailboxPerformance;
9use super::super::SyncEngine;
10
11impl SyncEngine {
12 pub(crate) async fn update_mailbox_performance(
24 &mut self,
25 peer_id: PeerId,
26 success: bool,
27 response_time: Duration,
28 ) {
29 let perf = self
30 .mailbox_performance
31 .entry(peer_id)
32 .or_insert_with(MailboxPerformance::new);
33
34 if success {
35 perf.success_count += 1;
36 perf.consecutive_failures = 0;
37 perf.last_success = Some(Instant::now());
38 self.backoff_manager.record_success(&peer_id);
39
40 if let Err(e) = self.known_mailboxes.increment_success(&peer_id).await {
42 error!("Failed to update mailbox {} success in database: {}", peer_id, e);
43 }
44 } else {
45 perf.failure_count += 1;
46 perf.consecutive_failures += 1;
47 perf.last_failure = Some(Instant::now());
48 self.backoff_manager.record_failure(peer_id);
49
50 if let Err(e) = self.known_mailboxes.increment_failure(&peer_id).await {
52 error!("Failed to update mailbox {} failure in database: {}", peer_id, e);
53 }
54 }
55
56 let new_weight = 0.3;
57 let old_weight = 1.0 - new_weight;
58 perf.avg_response_time = Duration::from_millis(
59 ((perf.avg_response_time.as_millis() as f64 * old_weight)
60 + (response_time.as_millis() as f64 * new_weight)) as u64,
61 );
62 }
63
64 pub(crate) async fn forget_failing_mailbox(&mut self, peer_id: PeerId) {
74 if self.discovered_mailboxes.remove(&peer_id) {
75 warn!(
76 "Temporarily forgetting failing mailbox {} due to persistent failures",
77 peer_id
78 );
79 self.backoff_manager.record_failure(peer_id);
80
81 if let Err(e) = self.known_mailboxes.remove_mailbox(&peer_id).await {
83 error!("Failed to remove mailbox {} from database: {}", peer_id, e);
84 }
85 }
86 }
87
88 pub(crate) async fn cleanup_failing_mailboxes(&mut self) {
93 let mut mailboxes_to_forget = Vec::new();
94
95 for peer_id in &self.discovered_mailboxes {
96 if self.should_forget_mailbox(*peer_id) {
97 mailboxes_to_forget.push(*peer_id);
98 }
99 }
100
101 for peer_id in mailboxes_to_forget {
102 self.forget_failing_mailbox(peer_id).await;
103 }
104 }
105}