p2p_chat/sync/engine/mailbox/
reliability.rs

1//! This module contains logic for tracking and managing the reliability
2//! of interactions with mailbox providers.
3use 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    /// Updates the performance metrics for a specific mailbox.
13    ///
14    /// Records whether an interaction was successful or a failure, updates
15    /// success/failure counts, last seen timestamps, and average response time.
16    /// It also interacts with the `BackoffManager` and persistent storage.
17    ///
18    /// # Arguments
19    ///
20    /// * `peer_id` - The `PeerId` of the mailbox.
21    /// * `success` - `true` if the interaction was successful, `false` otherwise.
22    /// * `response_time` - The duration of the interaction.
23    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            // Update database cache on success.
41            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            // Update database cache on failure.
51            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    /// Temporarily forgets a failing mailbox.
65    ///
66    /// If a mailbox is persistently failing, it is removed from the list of
67    /// discovered mailboxes and its failure is recorded in the `BackoffManager`
68    /// and persistent storage.
69    ///
70    /// # Arguments
71    ///
72    /// * `peer_id` - The `PeerId` of the mailbox to forget.
73    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            // Remove from database cache.
82            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    /// Cleans up failing mailboxes.
89    ///
90    /// Iterates through all discovered mailboxes and calls `forget_failing_mailbox`
91    /// for any that meet the criteria for being forgotten.
92    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}