mirror of
https://github.com/chatmail/core.git
synced 2026-04-17 21:46:35 +03:00
imap: fetch Inbox before scanning other folders
This commit is contained in:
@@ -17,6 +17,8 @@
|
||||
- call slow `delete_expired_imap_messages()` less often #3037
|
||||
- make synchronization of Seen status more robust in case unsolicited FETCH
|
||||
result without UID is returned #3022
|
||||
- fetch Inbox before scanning folders to ensure iOS does
|
||||
not kill the app before it gets to fetch the Inbox in background #3040
|
||||
|
||||
|
||||
## 1.72.0
|
||||
|
||||
@@ -10,7 +10,8 @@ use async_std::prelude::*;
|
||||
use super::{get_folder_meaning, get_folder_meaning_by_name};
|
||||
|
||||
impl Imap {
|
||||
pub(crate) async fn scan_folders(&mut self, context: &Context) -> Result<()> {
|
||||
/// Returns true if folders were scanned, false if scanning was postponed.
|
||||
pub(crate) async fn scan_folders(&mut self, context: &Context) -> Result<bool> {
|
||||
// First of all, debounce to once per minute:
|
||||
let mut last_scan = context.last_full_folder_scan.lock().await;
|
||||
if let Some(last_scan) = *last_scan {
|
||||
@@ -20,7 +21,7 @@ impl Imap {
|
||||
.await?;
|
||||
|
||||
if elapsed_secs < debounce_secs {
|
||||
return Ok(());
|
||||
return Ok(false);
|
||||
}
|
||||
}
|
||||
info!(context, "Starting full folder scan");
|
||||
@@ -98,7 +99,7 @@ impl Imap {
|
||||
}
|
||||
|
||||
last_scan.replace(Instant::now());
|
||||
Ok(())
|
||||
Ok(true)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -169,25 +169,42 @@ async fn fetch_idle(ctx: &Context, connection: &mut Imap, folder: Config) -> Int
|
||||
warn!(ctx, "{:#}", err);
|
||||
}
|
||||
|
||||
// Scan other folders before fetching from watched folder. This may result in the
|
||||
// messages being moved into the watched folder, for example from the Spam folder to
|
||||
// the Inbox folder.
|
||||
if folder == Config::ConfiguredInboxFolder {
|
||||
// Only scan on the Inbox thread in order to prevent parallel scans, which might lead to duplicate messages
|
||||
if let Err(err) = connection.scan_folders(ctx).await {
|
||||
// Don't reconnect, if there is a problem with the connection we will realize this when IDLEing
|
||||
// but maybe just one folder can't be selected or something
|
||||
warn!(ctx, "{}", err);
|
||||
}
|
||||
}
|
||||
|
||||
// fetch
|
||||
// Fetch the watched folder.
|
||||
if let Err(err) = connection.fetch_move_delete(ctx, &watch_folder).await {
|
||||
connection.trigger_reconnect(ctx).await;
|
||||
warn!(ctx, "{:#}", err);
|
||||
return InterruptInfo::new(false);
|
||||
}
|
||||
|
||||
// Scan additional folders only after finishing fetching the watched folder.
|
||||
//
|
||||
// On iOS the application has strictly limited time to work in background, so we may not
|
||||
// be able to scan all folders before time is up if there are many of them.
|
||||
if folder == Config::ConfiguredInboxFolder {
|
||||
// Only scan on the Inbox thread in order to prevent parallel scans, which might lead to duplicate messages
|
||||
match connection.scan_folders(ctx).await {
|
||||
Err(err) => {
|
||||
// Don't reconnect, if there is a problem with the connection we will realize this when IDLEing
|
||||
// but maybe just one folder can't be selected or something
|
||||
warn!(ctx, "{}", err);
|
||||
}
|
||||
Ok(true) => {
|
||||
// Fetch the watched folder again in case scanning other folder moved messages
|
||||
// there.
|
||||
//
|
||||
// In most cases this will select the watched folder and return because there are
|
||||
// no new messages. We want to select the watched folder anyway before going IDLE
|
||||
// there, so this does not take additional protocol round-trip.
|
||||
if let Err(err) = connection.fetch_move_delete(ctx, &watch_folder).await {
|
||||
connection.trigger_reconnect(ctx).await;
|
||||
warn!(ctx, "{:#}", err);
|
||||
return InterruptInfo::new(false);
|
||||
}
|
||||
}
|
||||
Ok(false) => {}
|
||||
}
|
||||
}
|
||||
|
||||
// Synchronize Seen flags.
|
||||
if let Err(err) = connection
|
||||
.sync_seen_flags(ctx, &watch_folder)
|
||||
|
||||
Reference in New Issue
Block a user