when first looking at a folder, look at "uid_next" as returned from server

and otherwise properly fetch the last messages to determine the last seen uid.
also add some tracing.
This commit is contained in:
holger krekel
2019-11-30 01:11:42 +01:00
parent 12187f3176
commit db22992ede
2 changed files with 26 additions and 31 deletions

View File

@@ -794,6 +794,7 @@ class TestOnlineAccount:
chat2 = ac2.qr_join_chat(qr) chat2 = ac2.qr_join_chat(qr)
assert chat2.id >= 10 assert chat2.id >= 10
wait_securejoin_inviter_progress(ac1, 1000) wait_securejoin_inviter_progress(ac1, 1000)
ac1._evlogger.get_matching("DC_EVENT_SECUREJOIN_MEMBER_ADDED")
lp.sec("ac2: read member added message") lp.sec("ac2: read member added message")
msg = ac2.wait_next_incoming_message() msg = ac2.wait_next_incoming_message()

View File

@@ -40,6 +40,7 @@ pub enum ImapActionResult {
} }
const PREFETCH_FLAGS: &str = "(UID ENVELOPE)"; const PREFETCH_FLAGS: &str = "(UID ENVELOPE)";
const JUST_UID : &str = "(UID)";
const BODY_FLAGS: &str = "(FLAGS BODY.PEEK[])"; const BODY_FLAGS: &str = "(FLAGS BODY.PEEK[])";
const SELECT_ALL: &str = "1:*"; const SELECT_ALL: &str = "1:*";
@@ -565,16 +566,6 @@ impl Imap {
let new_uid_validity = mailbox.uid_validity.unwrap(); let new_uid_validity = mailbox.uid_validity.unwrap();
if new_uid_validity != uid_validity { if new_uid_validity != uid_validity {
// First time this folder is selected or UIDVALIDITY has changed.
// Init lastseenuid and save it to config.
info!(
context,
"new_uid_validity={} current local uid_validity={} lastseenuid={}",
new_uid_validity,
uid_validity,
last_seen_uid
);
if mailbox.exists == 0 { if mailbox.exists == 0 {
info!(context, "Folder \"{}\" is empty.", folder.as_ref()); info!(context, "Folder \"{}\" is empty.", folder.as_ref());
@@ -586,35 +577,38 @@ impl Imap {
return Ok(false); return Ok(false);
} }
let list = if let Some(ref mut session) = &mut *self.session.lock().await { // uid_validity has changed or is being set the first time.
// `FETCH <message sequence number> (UID)` // find the last seen uid within the new uid_validity scope.
let set = format!("{}", mailbox.exists);
match session.fetch(set, PREFETCH_FLAGS).await { let new_last_seen_uid = if mailbox.uid_next.is_none() {
Ok(list) => list, warn!(context, "IMAP folder did not report uid_next, falling back to fetching");
Err(err) => { if let Some(ref mut session) = &mut *self.session.lock().await {
bail!("fetch failed: {}", err); // `FETCH <message sequence number> (UID)`
let set = format!("{}:*", mailbox.exists);
match session.fetch(set, JUST_UID).await {
Ok(list) => list.iter().last().and_then(|res| res.uid).unwrap_or_default(),
Err(err) => {
bail!("fetch failed: {:?}", err);
}
} }
} else {
return Err(Error::ImapNoConnection);
} }
} else { } else {
return Err(Error::ImapNoConnection); mailbox.uid_next.unwrap() - 1
}; };
last_seen_uid = list[0].uid.unwrap_or_else(|| 0); self.set_config_last_seen_uid(context, &folder, new_uid_validity, new_last_seen_uid);
// if the UIDVALIDITY has _changed_, decrease lastseenuid by one to avoid gaps (well add 1 below
if uid_validity > 0 && last_seen_uid > 1 {
last_seen_uid -= 1;
}
uid_validity = new_uid_validity;
self.set_config_last_seen_uid(context, &folder, uid_validity, last_seen_uid);
info!( info!(
context, context,
"lastseenuid initialized to {} for {}@{}", "uid change: new {}/{} current {}/{}",
last_seen_uid, new_last_seen_uid,
folder.as_ref(), new_uid_validity,
uid_validity, uid_validity,
last_seen_uid
); );
uid_validity = new_uid_validity;
last_seen_uid = new_last_seen_uid;
} }
let mut read_cnt = 0; let mut read_cnt = 0;