melib/imap: don't poll \Noselect mailboxes for updates

memfd
Manos Pitsidianakis 2020-09-13 00:24:26 +03:00
parent 46e3bb8074
commit 352f7505fc
Signed by: Manos Pitsidianakis
GPG Key ID: 73627C2F690DF710
2 changed files with 44 additions and 22 deletions

View File

@ -781,10 +781,21 @@ impl ImapConnection {
{ {
return Ok(None); return Ok(None);
} }
let (imap_path, permissions) = { let (imap_path, no_select, permissions) = {
let m = &self.uid_store.mailboxes.lock().await[&mailbox_hash]; let m = &self.uid_store.mailboxes.lock().await[&mailbox_hash];
(m.imap_path().to_string(), m.permissions.clone()) (
m.imap_path().to_string(),
m.no_select,
m.permissions.clone(),
)
}; };
if no_select {
return Err(MeliError::new(format!(
"Trying to select a \\NoSelect mailbox: {}",
&imap_path
))
.set_kind(crate::error::ErrorKind::Bug));
}
self.send_command(format!("SELECT \"{}\"", imap_path).as_bytes()) self.send_command(format!("SELECT \"{}\"", imap_path).as_bytes())
.await?; .await?;
self.read_response(ret, RequiredResponses::SELECT_REQUIRED) self.read_response(ret, RequiredResponses::SELECT_REQUIRED)
@ -856,18 +867,25 @@ impl ImapConnection {
{ {
return Ok(None); return Ok(None);
} }
self.send_command( let (imap_path, no_select) = {
format!( let m = &self.uid_store.mailboxes.lock().await[&mailbox_hash];
"EXAMINE \"{}\"", (m.imap_path().to_string(), m.no_select)
self.uid_store.mailboxes.lock().await[&mailbox_hash].imap_path() };
) if no_select {
.as_bytes(), return Err(MeliError::new(format!(
) "Trying to examine a \\NoSelect mailbox: {}",
.await?; &imap_path
))
.set_kind(crate::error::ErrorKind::Bug));
}
self.send_command(format!("EXAMINE \"{}\"", &imap_path).as_bytes())
.await?;
self.read_response(ret, RequiredResponses::EXAMINE_REQUIRED) self.read_response(ret, RequiredResponses::EXAMINE_REQUIRED)
.await?; .await?;
debug!("examine response {}", ret); debug!("examine response {}", ret);
let select_response = protocol_parser::select_response(&ret)?; let select_response = protocol_parser::select_response(&ret).chain_err_summary(|| {
format!("Could not parse select response for mailbox {}", imap_path)
})?;
self.stream.as_mut()?.current_mailbox = MailboxSelection::Examine(mailbox_hash); self.stream.as_mut()?.current_mailbox = MailboxSelection::Examine(mailbox_hash);
if !self if !self
.uid_store .uid_store

View File

@ -37,14 +37,16 @@ pub async fn poll_with_examine(kit: ImapWatchKit) -> Result<()> {
uid_store, uid_store,
} = kit; } = kit;
conn.connect().await?; conn.connect().await?;
let mailboxes: HashMap<MailboxHash, ImapMailbox> = {
let mailboxes_lck = timeout(uid_store.timeout, uid_store.mailboxes.lock()).await?;
mailboxes_lck.clone()
};
loop { loop {
let mailboxes: HashMap<MailboxHash, ImapMailbox> = { for (_, mailbox) in mailboxes.clone() {
let mailboxes_lck = timeout(uid_store.timeout, uid_store.mailboxes.lock()).await?;
mailboxes_lck.clone()
};
for (_, mailbox) in mailboxes {
examine_updates(mailbox, &mut conn, &uid_store).await?; examine_updates(mailbox, &mut conn, &uid_store).await?;
} }
//FIXME: make sleep duration configurable
smol::Timer::after(std::time::Duration::from_secs(3 * 60)).await;
} }
} }
@ -105,6 +107,10 @@ pub async fn idle(kit: ImapWatchKit) -> Result<()> {
uidvalidities.insert(mailbox_hash, select_response.uidvalidity); uidvalidities.insert(mailbox_hash, select_response.uidvalidity);
} }
} }
let mailboxes: HashMap<MailboxHash, ImapMailbox> = {
let mailboxes_lck = timeout(uid_store.timeout, uid_store.mailboxes.lock()).await?;
mailboxes_lck.clone()
};
conn.send_command(b"IDLE").await?; conn.send_command(b"IDLE").await?;
let mut blockn = ImapBlockingConnection::from(conn); let mut blockn = ImapBlockingConnection::from(conn);
let mut beat = std::time::Instant::now(); let mut beat = std::time::Instant::now();
@ -134,12 +140,7 @@ pub async fn idle(kit: ImapWatchKit) -> Result<()> {
if now.duration_since(watch) >= _5_MINS { if now.duration_since(watch) >= _5_MINS {
/* Time to poll all inboxes */ /* Time to poll all inboxes */
let mut conn = timeout(uid_store.timeout, main_conn.lock()).await?; let mut conn = timeout(uid_store.timeout, main_conn.lock()).await?;
let mailboxes: HashMap<MailboxHash, ImapMailbox> = { for (h, mailbox) in mailboxes.clone() {
let mailboxes_lck =
timeout(uid_store.timeout, uid_store.mailboxes.lock()).await?;
mailboxes_lck.clone()
};
for (h, mailbox) in mailboxes {
if mailbox_hash == h { if mailbox_hash == h {
continue; continue;
} }
@ -193,6 +194,9 @@ pub async fn examine_updates(
conn: &mut ImapConnection, conn: &mut ImapConnection,
uid_store: &Arc<UIDStore>, uid_store: &Arc<UIDStore>,
) -> Result<()> { ) -> Result<()> {
if mailbox.no_select {
return Ok(());
}
let mailbox_hash = mailbox.hash(); let mailbox_hash = mailbox.hash();
debug!("examining mailbox {} {}", mailbox_hash, mailbox.path()); debug!("examining mailbox {} {}", mailbox_hash, mailbox.path());
if let Some(new_envelopes) = conn.resync(mailbox_hash).await? { if let Some(new_envelopes) = conn.resync(mailbox_hash).await? {