p2p_chat/sync/engine/mailbox/
ack.rs1use anyhow::{anyhow, Result};
3use tracing::{debug, info, trace, warn};
4use uuid::Uuid;
5
6use crate::crypto::StorageEncryption;
7use crate::sync::retry::RetryPolicy;
8
9use super::super::SyncEngine;
10
11impl SyncEngine {
12 pub async fn acknowledge_mailbox_messages(&self, msg_ids: Vec<Uuid>) -> Result<()> {
27 if msg_ids.is_empty() {
28 return Ok(());
29 }
30
31 let Some(network) = &self.network else {
32 debug!("No network handle available for mailbox ACK");
33 return Ok(());
34 };
35
36 let recipient_hash =
37 StorageEncryption::derive_recipient_hash(&self.identity.hpke_public_key());
38
39 info!(
40 "Acknowledging {} messages to {} mailboxes",
41 msg_ids.len(),
42 self.get_mailbox_providers().len()
43 );
44
45 let mut total_deleted = 0;
46 let mut successful_acks = 0;
47 let mut failed_acks = 0;
48
49 let retry_policy = RetryPolicy::fast_mailbox();
50
51 for peer_id in self.get_mailbox_providers().iter() {
52 let ack_result = retry_policy
53 .retry_with_jitter(|| async {
54 network
55 .mailbox_ack(*peer_id, recipient_hash, msg_ids.clone())
56 .await
57 .map_err(|e| anyhow!("ACK failed: {}", e))
58 })
59 .await;
60
61 match ack_result {
62 Ok(deleted_count) => {
63 successful_acks += 1;
64 total_deleted += deleted_count;
65 if deleted_count > 0 {
66 info!(
67 "Mailbox {} confirmed deletion of {} messages",
68 peer_id, deleted_count
69 );
70 } else {
71 trace!("Mailbox {} had no messages to delete", peer_id);
72 }
73 }
74 Err(e) => {
75 failed_acks += 1;
76 warn!(
77 "Failed to ACK messages to mailbox {} after retries: {}",
78 peer_id, e
79 );
80 }
81 }
82 }
83
84 info!(
85 "ACK summary: {} messages deleted across {} mailboxes, {}/{} ACKs successful",
86 total_deleted,
87 successful_acks,
88 successful_acks,
89 successful_acks + failed_acks
90 );
91
92 if failed_acks > 0 {
93 warn!(
94 "Failed to ACK to {} mailboxes - messages may remain stored",
95 failed_acks
96 );
97 }
98
99 Ok(())
100 }
101}