mirror of
https://github.com/chatmail/core.git
synced 2026-04-20 23:16:30 +03:00
feat: reuse existing connections in background_fetch() if I/O is started
This commit is contained in:
@@ -515,8 +515,11 @@ impl Context {
|
|||||||
Ok(val)
|
Ok(val)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Does a background fetch
|
/// Does a single round of fetching from IMAP and returns.
|
||||||
/// pauses the scheduler and does one imap fetch, then unpauses and returns
|
///
|
||||||
|
/// Can be used even if I/O is currently stopped.
|
||||||
|
/// If I/O is currently stopped, starts a new IMAP connection
|
||||||
|
/// and fetches from Inbox and DeltaChat folders.
|
||||||
pub async fn background_fetch(&self) -> Result<()> {
|
pub async fn background_fetch(&self) -> Result<()> {
|
||||||
if !(self.is_configured().await?) {
|
if !(self.is_configured().await?) {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
@@ -524,35 +527,61 @@ impl Context {
|
|||||||
|
|
||||||
let address = self.get_primary_self_addr().await?;
|
let address = self.get_primary_self_addr().await?;
|
||||||
let time_start = tools::Time::now();
|
let time_start = tools::Time::now();
|
||||||
info!(self, "background_fetch started fetching {address}");
|
info!(self, "background_fetch started fetching {address}.");
|
||||||
|
|
||||||
let _pause_guard = self.scheduler.pause(self.clone()).await?;
|
if self.scheduler.is_running().await {
|
||||||
|
self.scheduler.maybe_network().await;
|
||||||
|
|
||||||
// connection
|
// Wait until fetching is finished.
|
||||||
let mut connection = Imap::new_configured(self, channel::bounded(1).1).await?;
|
// Ideally we could wait for connectivity change events,
|
||||||
let mut session = connection.prepare(self).await?;
|
// but sleep loop is good enough.
|
||||||
|
|
||||||
// fetch imap folders
|
// First 100 ms sleep in chunks of 10 ms.
|
||||||
for folder_meaning in [FolderMeaning::Inbox, FolderMeaning::Mvbox] {
|
for _ in 0..10 {
|
||||||
let (_, watch_folder) = convert_folder_meaning(self, folder_meaning).await?;
|
if self.all_work_done().await {
|
||||||
connection
|
break;
|
||||||
.fetch_move_delete(self, &mut session, &watch_folder, folder_meaning)
|
}
|
||||||
.await?;
|
tokio::time::sleep(std::time::Duration::from_millis(10)).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
// update quota (to send warning if full) - but only check it once in a while
|
// If we are not finished in 100 ms, keep waking up every 100 ms.
|
||||||
if self
|
while !self.all_work_done().await {
|
||||||
.quota_needs_update(DC_BACKGROUND_FETCH_QUOTA_CHECK_RATELIMIT)
|
tokio::time::sleep(std::time::Duration::from_millis(100)).await;
|
||||||
.await
|
}
|
||||||
{
|
} else {
|
||||||
if let Err(err) = self.update_recent_quota(&mut session).await {
|
// Pause the scheduler to ensure another connection does not start
|
||||||
warn!(self, "Failed to update quota: {err:#}.");
|
// while we are fetching on a dedicated connection.
|
||||||
|
let _pause_guard = self.scheduler.pause(self.clone()).await?;
|
||||||
|
|
||||||
|
// Start a new dedicated connection.
|
||||||
|
let mut connection = Imap::new_configured(self, channel::bounded(1).1).await?;
|
||||||
|
let mut session = connection.prepare(self).await?;
|
||||||
|
|
||||||
|
// Fetch IMAP folders.
|
||||||
|
// Inbox is fetched before Mvbox because fetching from Inbox
|
||||||
|
// may result in moving some messages to Mvbox.
|
||||||
|
for folder_meaning in [FolderMeaning::Inbox, FolderMeaning::Mvbox] {
|
||||||
|
let (_folder_config, watch_folder) =
|
||||||
|
convert_folder_meaning(self, folder_meaning).await?;
|
||||||
|
connection
|
||||||
|
.fetch_move_delete(self, &mut session, &watch_folder, folder_meaning)
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update quota (to send warning if full) - but only check it once in a while.
|
||||||
|
if self
|
||||||
|
.quota_needs_update(DC_BACKGROUND_FETCH_QUOTA_CHECK_RATELIMIT)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
if let Err(err) = self.update_recent_quota(&mut session).await {
|
||||||
|
warn!(self, "Failed to update quota: {err:#}.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
info!(
|
info!(
|
||||||
self,
|
self,
|
||||||
"background_fetch done for {address} took {:?}",
|
"background_fetch done for {address} took {:?}.",
|
||||||
time_elapsed(&time_start),
|
time_elapsed(&time_start),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user