mirror of
https://github.com/rustmailer/rustmailer.git
synced 2026-09-06 16:01:13 +00:00
fix(cache): use point query instead of scan when deleting local cache
This commit is contained in:
Vendored
+24
-24
@@ -2,7 +2,7 @@
|
||||
// Licensed under RustMailer License Agreement v1.0
|
||||
// Unauthorized copying, modification, or distribution is prohibited.
|
||||
|
||||
use std::{collections::HashSet, sync::Arc};
|
||||
use std::sync::Arc;
|
||||
|
||||
use native_db::*;
|
||||
use native_model::{native_model, Model};
|
||||
@@ -20,12 +20,13 @@ use crate::{
|
||||
},
|
||||
},
|
||||
database::{
|
||||
enqueue_delete_secondary_impl, filter_by_secondary_key_impl, manager::DB_MANAGER,
|
||||
safe_delete::RowFilter,
|
||||
batch_delete_impl, enqueue_delete_secondary_impl, filter_by_secondary_key_impl,
|
||||
manager::DB_MANAGER, safe_delete::RowFilter,
|
||||
},
|
||||
error::RustMailerResult,
|
||||
error::{code::ErrorCode, RustMailerResult},
|
||||
utils::envelope_hash,
|
||||
},
|
||||
raise_error,
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize, Object)]
|
||||
@@ -102,32 +103,31 @@ impl AddressEntity {
|
||||
mailbox_id: u64,
|
||||
to_delete_uid: &[u32],
|
||||
) -> RustMailerResult<()> {
|
||||
const BATCH_SIZE: usize = 50;
|
||||
|
||||
let to_delete_set: HashSet<u64> = to_delete_uid
|
||||
let hashes: Vec<u64> = to_delete_uid
|
||||
.iter()
|
||||
.map(|uid| envelope_hash(account_id, mailbox_id, *uid))
|
||||
.collect();
|
||||
|
||||
let to_delete_set = Arc::new(to_delete_set);
|
||||
let filter: RowFilter<AddressEntity> = Arc::new(move |e: &AddressEntity| {
|
||||
e.account_id == account_id && to_delete_set.contains(&e.envelope_hash)
|
||||
});
|
||||
enqueue_delete_secondary_impl(
|
||||
DB_MANAGER.envelope_db(),
|
||||
AddressEntityKey::mailbox_id,
|
||||
mailbox_id,
|
||||
filter,
|
||||
BATCH_SIZE,
|
||||
format!(
|
||||
"AddressEntity::clean_envelopes account_id={} mailbox_id={}",
|
||||
account_id, mailbox_id
|
||||
),
|
||||
)?;
|
||||
let deleted = batch_delete_impl(DB_MANAGER.envelope_db(), move |rw| {
|
||||
let mut to_delete = Vec::new();
|
||||
for hash in hashes {
|
||||
let entities: Vec<AddressEntity> = rw
|
||||
.scan()
|
||||
.secondary(AddressEntityKey::envelope_hash)
|
||||
.map_err(|e| raise_error!(format!("{:#?}", e), ErrorCode::InternalError))?
|
||||
.start_with(hash)
|
||||
.map_err(|e| raise_error!(format!("{:#?}", e), ErrorCode::InternalError))?
|
||||
.filter_map(Result::ok)
|
||||
.collect();
|
||||
to_delete.extend(entities);
|
||||
}
|
||||
Ok(to_delete)
|
||||
})
|
||||
.await?;
|
||||
|
||||
info!(
|
||||
"Enqueued deletion of address entities for mailbox_id={} account_id={}",
|
||||
mailbox_id, account_id
|
||||
"Deleted {} address entities for mailbox_id={} account_id={}",
|
||||
deleted, mailbox_id, account_id
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Vendored
+5
-4
@@ -86,6 +86,10 @@ impl EnvelopeFlagsManager {
|
||||
mailbox_id: u64,
|
||||
to_delete_uid: &[u32],
|
||||
) -> RustMailerResult<()> {
|
||||
EmailEnvelopeV3::clean_envelopes(account_id, mailbox_id, to_delete_uid).await?;
|
||||
MinimalEnvelope::clean_envelopes(account_id, mailbox_id, to_delete_uid).await?;
|
||||
AddressEntity::clean_envelopes(account_id, mailbox_id, to_delete_uid).await?;
|
||||
EmailThread::clean_envelopes(account_id, mailbox_id, to_delete_uid).await?;
|
||||
if let Some(mailboxes_map) = FLAGS_STATE_MAP.get(&account_id) {
|
||||
if let Some(flags_map) = mailboxes_map.get(&mailbox_id) {
|
||||
for uid in to_delete_uid {
|
||||
@@ -99,10 +103,7 @@ impl EnvelopeFlagsManager {
|
||||
FLAGS_STATE_MAP.remove(&account_id);
|
||||
}
|
||||
}
|
||||
EmailEnvelopeV3::clean_envelopes(account_id, mailbox_id, to_delete_uid).await?;
|
||||
MinimalEnvelope::clean_envelopes(account_id, mailbox_id, to_delete_uid).await?;
|
||||
AddressEntity::clean_envelopes(account_id, mailbox_id, to_delete_uid).await?;
|
||||
EmailThread::clean_envelopes(account_id, mailbox_id, to_delete_uid).await
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Clean all data associated with a specific mailbox for a given account.
|
||||
|
||||
Vendored
+25
-23
@@ -2,7 +2,7 @@
|
||||
// Licensed under RustMailer License Agreement v1.0
|
||||
// Unauthorized copying, modification, or distribution is prohibited.
|
||||
|
||||
use std::{collections::HashSet, sync::Arc};
|
||||
use std::sync::Arc;
|
||||
|
||||
use native_db::*;
|
||||
use native_model::{native_model, Model};
|
||||
@@ -26,9 +26,9 @@ use crate::{
|
||||
},
|
||||
common::Addr,
|
||||
database::{
|
||||
enqueue_delete_secondary_impl, filter_by_secondary_key_impl, manager::DB_MANAGER,
|
||||
paginate_secondary_scan_impl, safe_delete::RowFilter, secondary_find_impl, update_impl,
|
||||
with_transaction,
|
||||
batch_delete_impl, enqueue_delete_secondary_impl, filter_by_secondary_key_impl,
|
||||
manager::DB_MANAGER, paginate_secondary_scan_impl, safe_delete::RowFilter,
|
||||
secondary_find_impl, update_impl, with_transaction,
|
||||
},
|
||||
error::{code::ErrorCode, RustMailerResult},
|
||||
imap::section::{EmailBodyPart, ImapAttachment},
|
||||
@@ -475,27 +475,29 @@ impl EmailEnvelopeV3 {
|
||||
mailbox_id: u64,
|
||||
to_delete_uid: &[u32],
|
||||
) -> RustMailerResult<()> {
|
||||
const BATCH_SIZE: usize = 50;
|
||||
let to_delete_set: HashSet<u32> = to_delete_uid.iter().copied().collect();
|
||||
let to_delete_set = Arc::new(to_delete_set);
|
||||
let filter: RowFilter<EmailEnvelopeV3> = Arc::new(move |e: &EmailEnvelopeV3| {
|
||||
e.account_id == account_id && to_delete_set.contains(&e.uid)
|
||||
});
|
||||
enqueue_delete_secondary_impl(
|
||||
DB_MANAGER.envelope_db(),
|
||||
EmailEnvelopeV3Key::mailbox_id,
|
||||
mailbox_id,
|
||||
filter,
|
||||
BATCH_SIZE,
|
||||
format!(
|
||||
"EmailEnvelopeV3::clean_envelopes account_id={} mailbox_id={}",
|
||||
account_id, mailbox_id
|
||||
),
|
||||
)?;
|
||||
let hashes: Vec<u64> = to_delete_uid
|
||||
.iter()
|
||||
.map(|uid| envelope_hash(account_id, mailbox_id, *uid))
|
||||
.collect();
|
||||
|
||||
let deleted = batch_delete_impl(DB_MANAGER.envelope_db(), move |rw| {
|
||||
let mut to_delete = Vec::with_capacity(hashes.len());
|
||||
for hash in hashes {
|
||||
if let Some(envelope) = rw
|
||||
.get()
|
||||
.secondary::<EmailEnvelopeV3>(EmailEnvelopeV3Key::create_envelope_id, hash)
|
||||
.map_err(|e| raise_error!(format!("{:#?}", e), ErrorCode::InternalError))?
|
||||
{
|
||||
to_delete.push(envelope);
|
||||
}
|
||||
}
|
||||
Ok(to_delete)
|
||||
})
|
||||
.await?;
|
||||
|
||||
info!(
|
||||
"Enqueued deletion of envelopes for account_id={} mailbox_id={}",
|
||||
account_id, mailbox_id
|
||||
"Deleted {} envelopes for account_id={} mailbox_id={}",
|
||||
deleted, account_id, mailbox_id
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Vendored
+24
-22
@@ -2,7 +2,7 @@
|
||||
// Licensed under RustMailer License Agreement v1.0
|
||||
// Unauthorized copying, modification, or distribution is prohibited.
|
||||
|
||||
use std::{collections::HashSet, sync::Arc};
|
||||
use std::sync::Arc;
|
||||
|
||||
use native_db::*;
|
||||
use native_model::{native_model, Model};
|
||||
@@ -13,8 +13,8 @@ use crate::{
|
||||
modules::{
|
||||
cache::imap::{manager::EnvelopeFlagsManager, migration::EmailEnvelopeV3},
|
||||
database::{
|
||||
batch_insert_impl, enqueue_delete_secondary_impl, filter_by_secondary_key_impl,
|
||||
manager::DB_MANAGER, safe_delete::RowFilter, update_impl,
|
||||
batch_delete_impl, batch_insert_impl, enqueue_delete_secondary_impl,
|
||||
filter_by_secondary_key_impl, manager::DB_MANAGER, safe_delete::RowFilter, update_impl,
|
||||
},
|
||||
error::{code::ErrorCode, RustMailerResult},
|
||||
utils::envelope_hash,
|
||||
@@ -95,27 +95,29 @@ impl MinimalEnvelope {
|
||||
mailbox_id: u64,
|
||||
to_delete_uid: &[u32],
|
||||
) -> RustMailerResult<()> {
|
||||
const BATCH_SIZE: usize = 50;
|
||||
let to_delete_set: HashSet<u32> = to_delete_uid.iter().copied().collect();
|
||||
let to_delete_set = Arc::new(to_delete_set);
|
||||
let filter: RowFilter<MinimalEnvelope> = Arc::new(move |e: &MinimalEnvelope| {
|
||||
e.account_id == account_id && to_delete_set.contains(&e.uid)
|
||||
});
|
||||
enqueue_delete_secondary_impl(
|
||||
DB_MANAGER.envelope_db(),
|
||||
MinimalEnvelopeKey::mailbox_id,
|
||||
mailbox_id,
|
||||
filter,
|
||||
BATCH_SIZE,
|
||||
format!(
|
||||
"MinimalEnvelope::clean_envelopes account_id={} mailbox_id={}",
|
||||
account_id, mailbox_id
|
||||
),
|
||||
)?;
|
||||
let hashes: Vec<u64> = to_delete_uid
|
||||
.iter()
|
||||
.map(|uid| envelope_hash(account_id, mailbox_id, *uid))
|
||||
.collect();
|
||||
|
||||
let deleted = batch_delete_impl(DB_MANAGER.envelope_db(), move |rw| {
|
||||
let mut to_delete = Vec::with_capacity(hashes.len());
|
||||
for hash in hashes {
|
||||
if let Some(envelope) = rw
|
||||
.get()
|
||||
.primary::<MinimalEnvelope>(hash)
|
||||
.map_err(|e| raise_error!(format!("{:#?}", e), ErrorCode::InternalError))?
|
||||
{
|
||||
to_delete.push(envelope);
|
||||
}
|
||||
}
|
||||
Ok(to_delete)
|
||||
})
|
||||
.await?;
|
||||
|
||||
info!(
|
||||
"Enqueued deletion of minimal envelopes for account_id={} mailbox_id={}",
|
||||
account_id, mailbox_id
|
||||
"Deleted {} minimal envelopes for account_id={} mailbox_id={}",
|
||||
deleted, account_id, mailbox_id
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Vendored
+20
-23
@@ -2,7 +2,7 @@
|
||||
// Licensed under RustMailer License Agreement v1.0
|
||||
// Unauthorized copying, modification, or distribution is prohibited.
|
||||
|
||||
use std::{collections::HashSet, sync::Arc};
|
||||
use std::sync::Arc;
|
||||
|
||||
use futures::future::join_all;
|
||||
use native_db::*;
|
||||
@@ -23,8 +23,8 @@ use crate::{
|
||||
},
|
||||
},
|
||||
database::{
|
||||
enqueue_delete_secondary_impl, manager::DB_MANAGER, paginate_secondary_scan_impl,
|
||||
safe_delete::RowFilter,
|
||||
batch_delete_impl, enqueue_delete_secondary_impl, manager::DB_MANAGER,
|
||||
paginate_secondary_scan_impl, safe_delete::RowFilter,
|
||||
},
|
||||
error::{code::ErrorCode, RustMailerResult},
|
||||
rest::response::DataPage,
|
||||
@@ -112,32 +112,29 @@ impl EmailThread {
|
||||
mailbox_id: u64,
|
||||
to_delete_uid: &[u32],
|
||||
) -> RustMailerResult<()> {
|
||||
const BATCH_SIZE: usize = 50;
|
||||
|
||||
let to_delete_set: HashSet<u64> = to_delete_uid
|
||||
let hashes: Vec<u64> = to_delete_uid
|
||||
.iter()
|
||||
.map(|uid| envelope_hash(account_id, mailbox_id, *uid))
|
||||
.collect();
|
||||
|
||||
let to_delete_set = Arc::new(to_delete_set);
|
||||
let filter: RowFilter<EmailThread> = Arc::new(move |e: &EmailThread| {
|
||||
e.account_id == account_id && to_delete_set.contains(&e.envelope_id)
|
||||
});
|
||||
enqueue_delete_secondary_impl(
|
||||
DB_MANAGER.envelope_db(),
|
||||
EmailThreadKey::mailbox_id,
|
||||
mailbox_id,
|
||||
filter,
|
||||
BATCH_SIZE,
|
||||
format!(
|
||||
"EmailThread::clean_envelopes account_id={} mailbox_id={}",
|
||||
account_id, mailbox_id
|
||||
),
|
||||
)?;
|
||||
let deleted = batch_delete_impl(DB_MANAGER.envelope_db(), move |rw| {
|
||||
let mut to_delete = Vec::with_capacity(hashes.len());
|
||||
for hash in hashes {
|
||||
if let Some(thread) = rw
|
||||
.get()
|
||||
.secondary::<EmailThread>(EmailThreadKey::envelope_id, hash)
|
||||
.map_err(|e| raise_error!(format!("{:#?}", e), ErrorCode::InternalError))?
|
||||
{
|
||||
to_delete.push(thread);
|
||||
}
|
||||
}
|
||||
Ok(to_delete)
|
||||
})
|
||||
.await?;
|
||||
|
||||
info!(
|
||||
"Enqueued deletion of thread entities for mailbox_id={} account_id={}",
|
||||
mailbox_id, account_id
|
||||
"Deleted {} thread entities for account_id={} mailbox_id={}",
|
||||
deleted, account_id, mailbox_id
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user