imap: skip sync flags update if highest modseq has not increased

This commit is contained in:
link2xt
2022-01-30 20:12:02 +00:00
parent 8aa6decbf9
commit 48eb400a69
5 changed files with 48 additions and 6 deletions

View File

@@ -1023,23 +1023,33 @@ impl Imap {
.as_ref()
.with_context(|| format!("No mailbox selected, folder: {}", folder))?;
// Check if the mailbox supports MODSEQ.
// We are not interested in actual value of HIGHESTMODSEQ.
if mailbox.highest_modseq.is_none() {
let remote_highest_modseq = if let Some(remote_highest_modseq) = mailbox.highest_modseq {
remote_highest_modseq
} else {
info!(
context,
"Mailbox {} does not support mod-sequences, skipping flag synchronization.", folder
);
return Ok(());
};
let mut highest_modseq = get_modseq(context, folder)
.await
.with_context(|| format!("failed to get MODSEQ for folder {}", folder))?;
if highest_modseq >= remote_highest_modseq {
info!(
context,
"MODSEQ {} is already new, HIGHESTMODSEQ={}, skipping seen flag update",
highest_modseq,
remote_highest_modseq
);
return Ok(());
}
let mut updated_chat_ids = BTreeSet::new();
let uid_validity = get_uidvalidity(context, folder)
.await
.with_context(|| format!("failed to get UID validity for folder {}", folder))?;
let mut highest_modseq = get_modseq(context, folder)
.await
.with_context(|| format!("failed to get MODSEQ for folder {}", folder))?;
let mut list = session
.uid_fetch("1:*", format!("(FLAGS) (CHANGEDSINCE {})", highest_modseq))
.await
@@ -1074,6 +1084,10 @@ impl Imap {
}
}
if remote_highest_modseq > highest_modseq {
// We haven't seen the message with the highest MODSEQ, maybe it was deleted already.
highest_modseq = remote_highest_modseq;
}
set_modseq(context, folder, highest_modseq)
.await
.with_context(|| format!("failed to set MODSEQ for folder {}", folder))?;
@@ -1570,6 +1584,23 @@ impl Imap {
Ok(())
}
/// Update HIGHESTMODSEQ on selected mailbox.
///
/// Should be called when MODSEQ is seen on the response, such as IDLE response.
pub(crate) fn update_modseq(&mut self, modseq: u64) {
self.config.selected_mailbox =
self.config
.selected_mailbox
.as_ref()
.map(|mailbox| Mailbox {
highest_modseq: Some(std::cmp::max(
mailbox.highest_modseq.unwrap_or_default(),
modseq,
)),
..mailbox.clone()
});
}
/// Return whether the server sent an unsolicited EXISTS response.
/// Drains all responses from `session.unsolicited_responses` in the process.
/// If this returns `true`, this means that new emails arrived and you should