Browse Source

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

memfd
Manos Pitsidianakis 1 year ago
parent
commit
352f7505fc
Signed by untrusted user: epilys GPG Key ID: 73627C2F690DF710
  1. 40
      melib/src/backends/imap/connection.rs
  2. 26
      melib/src/backends/imap/watch.rs

40
melib/src/backends/imap/connection.rs

@ -781,10 +781,21 @@ impl ImapConnection {
{
return Ok(None);
}
let (imap_path, permissions) = {
let (imap_path, no_select, permissions) = {
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())
.await?;
self.read_response(ret, RequiredResponses::SELECT_REQUIRED)
@ -856,18 +867,25 @@ impl ImapConnection {
{
return Ok(None);
}
self.send_command(
format!(
"EXAMINE \"{}\"",
self.uid_store.mailboxes.lock().await[&mailbox_hash].imap_path()
)
.as_bytes(),
)
.await?;
let (imap_path, no_select) = {
let m = &self.uid_store.mailboxes.lock().await[&mailbox_hash];
(m.imap_path().to_string(), m.no_select)
};
if no_select {
return Err(MeliError::new(format!(
"Trying to examine a \\NoSelect mailbox: {}",
&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)
.await?;
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);
if !self
.uid_store

26
melib/src/backends/imap/watch.rs

@ -37,14 +37,16 @@ pub async fn poll_with_examine(kit: ImapWatchKit) -> Result<()> {
uid_store,
} = kit;
conn.connect().await?;
let mailboxes: HashMap<MailboxHash, ImapMailbox> = {
let mailboxes_lck = timeout(uid_store.timeout, uid_store.mailboxes.lock()).await?;
mailboxes_lck.clone()
};
loop {
let mailboxes: HashMap<MailboxHash, ImapMailbox> = {
let mailboxes_lck = timeout(uid_store.timeout, uid_store.mailboxes.lock()).await?;
mailboxes_lck.clone()
};
for (_, mailbox) in mailboxes {
for (_, mailbox) in mailboxes.clone() {
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);
}
}
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?;
let mut blockn = ImapBlockingConnection::from(conn);
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 {
/* Time to poll all inboxes */
let mut conn = timeout(uid_store.timeout, main_conn.lock()).await?;
let mailboxes: HashMap<MailboxHash, ImapMailbox> = {
let mailboxes_lck =
timeout(uid_store.timeout, uid_store.mailboxes.lock()).await?;
mailboxes_lck.clone()
};
for (h, mailbox) in mailboxes {
for (h, mailbox) in mailboxes.clone() {
if mailbox_hash == h {
continue;
}
@ -193,6 +194,9 @@ pub async fn examine_updates(
conn: &mut ImapConnection,
uid_store: &Arc<UIDStore>,
) -> Result<()> {
if mailbox.no_select {
return Ok(());
}
let mailbox_hash = mailbox.hash();
debug!("examining mailbox {} {}", mailbox_hash, mailbox.path());
if let Some(new_envelopes) = conn.resync(mailbox_hash).await? {

Loading…
Cancel
Save