mirror of
https://github.com/chatmail/core.git
synced 2026-05-24 17:26:30 +03:00
refactor: Move quota_needs_update calculation to a separate function (#5683)
And add a unit test for this function. At least this way we protect from the recently fixed bug when a wrong comparison operator was used.
This commit is contained in:
@@ -541,18 +541,10 @@ impl Context {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// update quota (to send warning if full) - but only check it once in a while
|
// update quota (to send warning if full) - but only check it once in a while
|
||||||
let quota_needs_update = {
|
if self
|
||||||
let quota = self.quota.read().await;
|
.quota_needs_update(DC_BACKGROUND_FETCH_QUOTA_CHECK_RATELIMIT)
|
||||||
quota
|
.await
|
||||||
.as_ref()
|
{
|
||||||
.filter(|quota| {
|
|
||||||
time_elapsed("a.modified)
|
|
||||||
< Duration::from_secs(DC_BACKGROUND_FETCH_QUOTA_CHECK_RATELIMIT)
|
|
||||||
})
|
|
||||||
.is_none()
|
|
||||||
};
|
|
||||||
|
|
||||||
if quota_needs_update {
|
|
||||||
if let Err(err) = self.update_recent_quota(&mut session).await {
|
if let Err(err) = self.update_recent_quota(&mut session).await {
|
||||||
warn!(self, "Failed to update quota: {err:#}.");
|
warn!(self, "Failed to update quota: {err:#}.");
|
||||||
}
|
}
|
||||||
|
|||||||
34
src/quota.rs
34
src/quota.rs
@@ -1,6 +1,7 @@
|
|||||||
//! # Support for IMAP QUOTA extension.
|
//! # Support for IMAP QUOTA extension.
|
||||||
|
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
use anyhow::{anyhow, Context as _, Result};
|
use anyhow::{anyhow, Context as _, Result};
|
||||||
use async_imap::types::{Quota, QuotaResource};
|
use async_imap::types::{Quota, QuotaResource};
|
||||||
@@ -11,7 +12,7 @@ use crate::context::Context;
|
|||||||
use crate::imap::scan_folders::get_watched_folders;
|
use crate::imap::scan_folders::get_watched_folders;
|
||||||
use crate::imap::session::Session as ImapSession;
|
use crate::imap::session::Session as ImapSession;
|
||||||
use crate::message::{Message, Viewtype};
|
use crate::message::{Message, Viewtype};
|
||||||
use crate::tools;
|
use crate::tools::{self, time_elapsed};
|
||||||
use crate::{stock_str, EventType};
|
use crate::{stock_str, EventType};
|
||||||
|
|
||||||
/// warn about a nearly full mailbox after this usage percentage is reached.
|
/// warn about a nearly full mailbox after this usage percentage is reached.
|
||||||
@@ -102,6 +103,16 @@ pub fn needs_quota_warning(curr_percentage: u64, warned_at_percentage: u64) -> b
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Context {
|
impl Context {
|
||||||
|
/// Returns whether the quota value needs an update. If so, `update_recent_quota()` should be
|
||||||
|
/// called.
|
||||||
|
pub(crate) async fn quota_needs_update(&self, ratelimit_secs: u64) -> bool {
|
||||||
|
let quota = self.quota.read().await;
|
||||||
|
quota
|
||||||
|
.as_ref()
|
||||||
|
.filter(|quota| time_elapsed("a.modified) < Duration::from_secs(ratelimit_secs))
|
||||||
|
.is_none()
|
||||||
|
}
|
||||||
|
|
||||||
/// Updates `quota.recent`, sets `quota.modified` to the current time
|
/// Updates `quota.recent`, sets `quota.modified` to the current time
|
||||||
/// and emits an event to let the UIs update connectivity view.
|
/// and emits an event to let the UIs update connectivity view.
|
||||||
///
|
///
|
||||||
@@ -155,6 +166,7 @@ impl Context {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use crate::test_utils::TestContextManager;
|
||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn test_needs_quota_warning() -> Result<()> {
|
async fn test_needs_quota_warning() -> Result<()> {
|
||||||
@@ -183,4 +195,24 @@ mod tests {
|
|||||||
assert!(QUOTA_ERROR_THRESHOLD_PERCENTAGE < 100);
|
assert!(QUOTA_ERROR_THRESHOLD_PERCENTAGE < 100);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
|
async fn test_quota_needs_update() {
|
||||||
|
let mut tcm = TestContextManager::new();
|
||||||
|
let t = &tcm.unconfigured().await;
|
||||||
|
const TIMEOUT: u64 = 60;
|
||||||
|
assert!(t.quota_needs_update(TIMEOUT).await);
|
||||||
|
|
||||||
|
*t.quota.write().await = Some(QuotaInfo {
|
||||||
|
recent: Ok(Default::default()),
|
||||||
|
modified: tools::Time::now() - Duration::from_secs(TIMEOUT + 1),
|
||||||
|
});
|
||||||
|
assert!(t.quota_needs_update(TIMEOUT).await);
|
||||||
|
|
||||||
|
*t.quota.write().await = Some(QuotaInfo {
|
||||||
|
recent: Ok(Default::default()),
|
||||||
|
modified: tools::Time::now(),
|
||||||
|
});
|
||||||
|
assert!(!t.quota_needs_update(TIMEOUT).await);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ use std::cmp;
|
|||||||
use std::iter::{self, once};
|
use std::iter::{self, once};
|
||||||
use std::num::NonZeroUsize;
|
use std::num::NonZeroUsize;
|
||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
use std::time::Duration;
|
|
||||||
|
|
||||||
use anyhow::{bail, Context as _, Error, Result};
|
use anyhow::{bail, Context as _, Error, Result};
|
||||||
use async_channel::{self as channel, Receiver, Sender};
|
use async_channel::{self as channel, Receiver, Sender};
|
||||||
@@ -473,14 +472,7 @@ async fn inbox_fetch_idle(ctx: &Context, imap: &mut Imap, mut session: Session)
|
|||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
// Update quota no more than once a minute.
|
// Update quota no more than once a minute.
|
||||||
let quota_needs_update = {
|
if ctx.quota_needs_update(60).await {
|
||||||
let quota = ctx.quota.read().await;
|
|
||||||
quota
|
|
||||||
.as_ref()
|
|
||||||
.filter(|quota| time_elapsed("a.modified) < Duration::from_secs(60))
|
|
||||||
.is_none()
|
|
||||||
};
|
|
||||||
if quota_needs_update {
|
|
||||||
if let Err(err) = ctx.update_recent_quota(&mut session).await {
|
if let Err(err) = ctx.update_recent_quota(&mut session).await {
|
||||||
warn!(ctx, "Failed to update quota: {:#}.", err);
|
warn!(ctx, "Failed to update quota: {:#}.", err);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user