This commit is contained in:
rustmailer
2026-05-14 22:11:10 +08:00
parent 907e59027d
commit 3fa4fe453c
24 changed files with 83 additions and 9 deletions
+6 -1
View File
@@ -136,7 +136,12 @@ impl DownloadState {
let mut updated = current.clone();
updated.last_trigger_at = utc_now!();
if let Some(old_session) = updated.active_session.take() {
if let Some(mut old_session) = updated.active_session.take() {
if old_session.status == DownloadStatus::Running {
old_session.status = DownloadStatus::Cancelled;
old_session.end_time = Some(utc_now!());
old_session.message = Some("Interrupted by a new download session.".into());
}
updated.history.push(old_session);
if updated.history.len() > 30 {
updated.history.remove(0);
+10
View File
@@ -175,6 +175,16 @@ pub async fn detect_mailbox_changes(
"Account {}: New folders detected: {:?}",
account.id, new_folders
);
if account.auto_download_new_mailboxes.unwrap_or(false) {
let mut updated: Vec<String> = download_folders.to_vec();
updated.extend(new_folders.iter().cloned());
AccountModel::update_download_folders(account.id, updated)?;
info!(
"Account {}: Auto-added {} new folders to download list",
account.id,
new_folders.len()
);
}
}
// Update known folders only if there were changes
+18 -7
View File
@@ -62,10 +62,22 @@ impl AccountDownTask {
}
}
async fn is_busy(&self, account_id: u64) -> bool {
self.busy_accounts.lock().await.contains(&account_id)
/// Atomically check and set busy. Returns true if we claimed the slot,
/// false if another task is already busy on this account.
async fn try_set_busy(&self, account_id: u64) -> bool {
let mut guard = self.busy_accounts.lock().await;
if guard.contains(&account_id) {
false
} else {
guard.insert(account_id);
true
}
}
// async fn is_busy(&self, account_id: u64) -> bool {
// self.busy_accounts.lock().await.contains(&account_id)
// }
pub async fn start_download_task(&self, account_id: u64, email: String) {
let task_name = format!("account-download-task-{}-{}", account_id, &email);
let periodic_task = PeriodicTask::new(&task_name);
@@ -85,7 +97,7 @@ impl AccountDownTask {
return Ok(());
}
if SYNC_TASKS.is_busy(account_id).await {
if !SYNC_TASKS.try_set_busy(account_id).await {
warn!(
"Account {}: Scheduled task skipped (Previous sync still active).",
account_id
@@ -93,7 +105,6 @@ impl AccountDownTask {
return Ok(());
}
SYNC_TASKS.set_busy(account_id, true).await;
let _busy_guard = scopeguard::guard(account_id, |id| {
tokio::spawn(async move {
SYNC_TASKS.set_busy(id, false).await;
@@ -205,9 +216,9 @@ impl AccountDownTask {
ErrorCode::Forbidden
));
}
if self.is_busy(account_id).await {
if !self.try_set_busy(account_id).await {
return Err(raise_error!(
"The background synchronization is currently active. Please try again in a few seconds.".into(),
"The background synchronization is currently active. Please try again in a few seconds.".into(),
ErrorCode::Forbidden
));
}
@@ -216,7 +227,7 @@ impl AccountDownTask {
let cancel_token = CancellationToken::new();
let token_clone = cancel_token.clone();
let handle = tokio::spawn(async move {
SYNC_TASKS.set_busy(account_id, true).await;
// busy already claimed by caller via try_set_busy
let _cleanup = scopeguard::guard(account_id, |id| {
tokio::spawn(async move {
SYNC_TASKS.set_busy(id, false).await;