melib/imap: small cleanups

memfd
Manos Pitsidianakis 2020-08-26 20:06:06 +03:00
parent f02dde46da
commit e9a80b32ac
Signed by: Manos Pitsidianakis
GPG Key ID: 73627C2F690DF710
2 changed files with 50 additions and 81 deletions

View File

@ -466,6 +466,10 @@ impl MailBackend for ImapType {
let uid_store = self.uid_store.clone(); let uid_store = self.uid_store.clone();
let connection = self.connection.clone(); let connection = self.connection.clone();
Ok(Box::pin(async move { Ok(Box::pin(async move {
let mut response = String::with_capacity(8 * 1024);
let mut conn = connection.lock().await;
conn.select_mailbox(mailbox_hash, &mut response, true)
.await?;
let path = { let path = {
let mailboxes = uid_store.mailboxes.lock().await; let mailboxes = uid_store.mailboxes.lock().await;
@ -481,8 +485,6 @@ impl MailBackend for ImapType {
mailbox.imap_path().to_string() mailbox.imap_path().to_string()
}; };
let mut response = String::with_capacity(8 * 1024);
let mut conn = connection.lock().await;
let flags = flags.unwrap_or_else(Flag::empty); let flags = flags.unwrap_or_else(Flag::empty);
let has_literal_plus: bool = uid_store let has_literal_plus: bool = uid_store
.capabilities .capabilities
@ -556,7 +558,7 @@ impl MailBackend for ImapType {
.ok_or_else(|| MeliError::new("Destination mailbox not found"))?; .ok_or_else(|| MeliError::new("Destination mailbox not found"))?;
if !mailbox.permissions.lock().unwrap().create_messages { if !mailbox.permissions.lock().unwrap().create_messages {
return Err(MeliError::new(format!( return Err(MeliError::new(format!(
"You are not allowed to delete messages from mailbox {}", "You are not allowed to create messages in mailbox {}",
mailbox.path() mailbox.path()
))); )));
} }
@ -804,6 +806,7 @@ impl MailBackend for ImapType {
let mut response = String::with_capacity(8 * 1024); let mut response = String::with_capacity(8 * 1024);
{ {
let mut conn_lck = connection.lock().await; let mut conn_lck = connection.lock().await;
conn_lck.unselect().await?;
conn_lck conn_lck
.send_command(format!("CREATE \"{}\"", path,).as_bytes()) .send_command(format!("CREATE \"{}\"", path,).as_bytes())
@ -835,11 +838,9 @@ impl MailBackend for ImapType {
let new_mailbox_fut = self.mailboxes(); let new_mailbox_fut = self.mailboxes();
Ok(Box::pin(async move { Ok(Box::pin(async move {
let imap_path: String; let imap_path: String;
let no_select: bool;
let is_subscribed: bool; let is_subscribed: bool;
{ {
let mailboxes = uid_store.mailboxes.lock().await; let mailboxes = uid_store.mailboxes.lock().await;
no_select = mailboxes[&mailbox_hash].no_select;
is_subscribed = mailboxes[&mailbox_hash].is_subscribed(); is_subscribed = mailboxes[&mailbox_hash].is_subscribed();
imap_path = mailboxes[&mailbox_hash].imap_path().to_string(); imap_path = mailboxes[&mailbox_hash].imap_path().to_string();
let permissions = mailboxes[&mailbox_hash].permissions(); let permissions = mailboxes[&mailbox_hash].permissions();
@ -850,15 +851,9 @@ impl MailBackend for ImapType {
let mut response = String::with_capacity(8 * 1024); let mut response = String::with_capacity(8 * 1024);
{ {
let mut conn_lck = connection.lock().await; let mut conn_lck = connection.lock().await;
let current_mailbox = conn_lck.stream.as_ref()?.current_mailbox; /* make sure mailbox is not selected before it gets deleted, otherwise
if !no_select * connection gets dropped by server */
&& (current_mailbox == MailboxSelection::Examine(mailbox_hash) conn_lck.unselect().await?;
|| current_mailbox == MailboxSelection::Select(mailbox_hash))
{
/* make sure mailbox is not selected before it gets deleted, otherwise
* connection gets dropped by server */
conn_lck.unselect().await?;
}
if is_subscribed { if is_subscribed {
conn_lck conn_lck
.send_command(format!("UNSUBSCRIBE \"{}\"", &imap_path).as_bytes()) .send_command(format!("UNSUBSCRIBE \"{}\"", &imap_path).as_bytes())

View File

@ -33,11 +33,10 @@ pub async fn poll_with_examine(kit: ImapWatchKit) -> Result<()> {
debug!("poll with examine"); debug!("poll with examine");
let ImapWatchKit { let ImapWatchKit {
mut conn, mut conn,
main_conn, main_conn: _,
uid_store, uid_store,
} = kit; } = kit;
conn.connect().await?; conn.connect().await?;
let mut response = String::with_capacity(8 * 1024);
loop { loop {
let mailboxes: HashMap<MailboxHash, ImapMailbox> = { let mailboxes: HashMap<MailboxHash, ImapMailbox> = {
let mailboxes_lck = timeout(Duration::from_secs(3), uid_store.mailboxes.lock()).await?; let mailboxes_lck = timeout(Duration::from_secs(3), uid_store.mailboxes.lock()).await?;
@ -46,11 +45,6 @@ pub async fn poll_with_examine(kit: ImapWatchKit) -> Result<()> {
for (_, mailbox) in mailboxes { for (_, mailbox) in mailboxes {
examine_updates(mailbox, &mut conn, &uid_store).await?; examine_updates(mailbox, &mut conn, &uid_store).await?;
} }
let mut main_conn = timeout(Duration::from_secs(3), main_conn.lock()).await?;
main_conn.send_command(b"NOOP").await?;
main_conn
.read_response(&mut response, RequiredResponses::empty())
.await?;
} }
} }
@ -79,52 +73,36 @@ pub async fn idle(kit: ImapWatchKit) -> Result<()> {
}; };
let mailbox_hash = mailbox.hash(); let mailbox_hash = mailbox.hash();
let mut response = String::with_capacity(8 * 1024); let mut response = String::with_capacity(8 * 1024);
conn.send_command(format!("SELECT \"{}\"", mailbox.imap_path()).as_bytes()) let select_response = conn
.await?; .select_mailbox(mailbox_hash, &mut response, true)
conn.read_response(&mut response, RequiredResponses::SELECT_REQUIRED) .await?
.await?; .unwrap();
debug!("select response {}", &response); debug!("select response {}", &response);
{ {
let mut prev_exists = mailbox.exists.lock().unwrap(); let mut uidvalidities = uid_store.uidvalidity.lock().unwrap();
match protocol_parser::select_response(&response) {
Ok(ok) => {
{
let uidvalidities = uid_store.uidvalidity.lock().unwrap();
if let Some(v) = uidvalidities.get(&mailbox_hash) { if let Some(v) = uidvalidities.get(&mailbox_hash) {
if *v != ok.uidvalidity { if *v != select_response.uidvalidity {
conn.add_refresh_event(RefreshEvent { let cache_handle = cache::CacheHandle::get(uid_store.clone())?;
account_hash: uid_store.account_hash, cache_handle.clear(
mailbox_hash, mailbox_hash,
kind: RefreshEventKind::Rescan, select_response.uidvalidity,
}); select_response.highestmodseq.and_then(|i| i.ok()),
prev_exists.clear(); )?;
/* conn.add_refresh_event(RefreshEvent {
uid_store.uid_index.lock().unwrap().clear(); account_hash: uid_store.account_hash,
uid_store.hash_index.lock().unwrap().clear(); mailbox_hash,
uid_store.byte_cache.lock().unwrap().clear(); kind: RefreshEventKind::Rescan,
*/ });
} /*
} else { uid_store.uid_index.lock().unwrap().clear();
conn.add_refresh_event(RefreshEvent { uid_store.hash_index.lock().unwrap().clear();
account_hash: uid_store.account_hash, uid_store.byte_cache.lock().unwrap().clear();
mailbox_hash, */
kind: RefreshEventKind::Rescan,
});
return Err(MeliError::new(format!(
"Unknown mailbox: {} {}",
mailbox.path(),
mailbox_hash
)));
}
}
debug!(&ok);
} }
Err(e) => { } else {
debug!("{:?}", e); uidvalidities.insert(mailbox_hash, select_response.uidvalidity);
return Err(e).chain_err_summary(|| "could not select mailbox"); }
}
};
} }
conn.send_command(b"IDLE").await?; conn.send_command(b"IDLE").await?;
let mut blockn = ImapBlockingConnection::from(conn); let mut blockn = ImapBlockingConnection::from(conn);
@ -134,7 +112,7 @@ pub async fn idle(kit: ImapWatchKit) -> Result<()> {
const _26_MINS: std::time::Duration = std::time::Duration::from_secs(26 * 60); const _26_MINS: std::time::Duration = std::time::Duration::from_secs(26 * 60);
/* duration interval to check other mailboxes for changes */ /* duration interval to check other mailboxes for changes */
const _5_MINS: std::time::Duration = std::time::Duration::from_secs(5 * 60); const _5_MINS: std::time::Duration = std::time::Duration::from_secs(5 * 60);
while let Some(line) = blockn.as_stream().await { while let Some(line) = timeout(Duration::from_secs(35 * 60), blockn.as_stream()).await? {
let now = std::time::Instant::now(); let now = std::time::Instant::now();
if now.duration_since(beat) >= _26_MINS { if now.duration_since(beat) >= _26_MINS {
let mut main_conn_lck = timeout(Duration::from_secs(3), main_conn.lock()).await?; let mut main_conn_lck = timeout(Duration::from_secs(3), main_conn.lock()).await?;
@ -158,13 +136,18 @@ pub async fn idle(kit: ImapWatchKit) -> Result<()> {
timeout(Duration::from_secs(3), uid_store.mailboxes.lock()).await?; timeout(Duration::from_secs(3), uid_store.mailboxes.lock()).await?;
mailboxes_lck.clone() mailboxes_lck.clone()
}; };
for (_, mailbox) in mailboxes { for (h, mailbox) in mailboxes {
if mailbox_hash == h {
continue;
}
examine_updates(mailbox, &mut conn, &uid_store).await?; examine_updates(mailbox, &mut conn, &uid_store).await?;
} }
watch = now; watch = now;
} }
{ {
let mut conn = timeout(Duration::from_secs(3), main_conn.lock()).await?; let mut conn = timeout(Duration::from_secs(10), main_conn.lock()).await?;
conn.examine_mailbox(mailbox_hash, &mut response, false)
.await?;
conn.process_untagged(to_str!(&line)).await?; conn.process_untagged(to_str!(&line)).await?;
} }
*uid_store.is_online.lock().unwrap() = (Instant::now(), Ok(())); *uid_store.is_online.lock().unwrap() = (Instant::now(), Ok(()));
@ -201,14 +184,14 @@ pub async fn examine_updates(
} }
} else { } else {
let mut response = String::with_capacity(8 * 1024); let mut response = String::with_capacity(8 * 1024);
conn.examine_mailbox(mailbox_hash, &mut response, true) let select_response = conn
.await?; .examine_mailbox(mailbox_hash, &mut response, true)
.await?
.unwrap();
*uid_store.is_online.lock().unwrap() = (Instant::now(), Ok(())); *uid_store.is_online.lock().unwrap() = (Instant::now(), Ok(()));
let select_response = protocol_parser::select_response(&response)
.chain_err_summary(|| "could not select mailbox")?;
debug!(&select_response); debug!(&select_response);
{ {
let uidvalidities = uid_store.uidvalidity.lock().unwrap(); let mut uidvalidities = uid_store.uidvalidity.lock().unwrap();
if let Some(v) = uidvalidities.get(&mailbox_hash) { if let Some(v) = uidvalidities.get(&mailbox_hash) {
if *v != select_response.uidvalidity { if *v != select_response.uidvalidity {
@ -231,16 +214,7 @@ pub async fn examine_updates(
return Ok(()); return Ok(());
} }
} else { } else {
conn.add_refresh_event(RefreshEvent { uidvalidities.insert(mailbox_hash, select_response.uidvalidity);
account_hash: uid_store.account_hash,
mailbox_hash,
kind: RefreshEventKind::Rescan,
});
return Err(MeliError::new(format!(
"Unknown mailbox: {} {}",
mailbox.path(),
mailbox_hash
)));
} }
} }
let mut cache_handle = cache::CacheHandle::get(uid_store.clone())?; let mut cache_handle = cache::CacheHandle::get(uid_store.clone())?;