summaryrefslogtreecommitdiffstats
path: root/melib
diff options
context:
space:
mode:
authorManos Pitsidianakis <el13635@mail.ntua.gr>2020-09-15 12:59:31 +0300
committerManos Pitsidianakis <el13635@mail.ntua.gr>2020-09-16 13:11:28 +0300
commit0e2641f7ed8bdde9ef87923b049f3fd1ebd382d0 (patch)
treea289838b002f6ad7cad3752bb3c3db9a2d0a70c9 /melib
parent67c722958bb8053fd92212bde253df7b6093433c (diff)
melib/imap: always retry connection in watch()
Diffstat (limited to 'melib')
-rw-r--r--melib/src/backends/imap.rs36
-rw-r--r--melib/src/backends/imap/watch.rs48
2 files changed, 44 insertions, 40 deletions
diff --git a/melib/src/backends/imap.rs b/melib/src/backends/imap.rs
index a9ca5d5c..cb4d994b 100644
--- a/melib/src/backends/imap.rs
+++ b/melib/src/backends/imap.rs
@@ -444,7 +444,7 @@ impl MailBackend for ImapType {
}
fn watch(&self) -> ResultFuture<()> {
- let conn = ImapConnection::new_connection(&self.server_conf, self.uid_store.clone());
+ let server_conf = self.server_conf.clone();
let main_conn = self.connection.clone();
let uid_store = self.uid_store.clone();
let has_idle: bool = match self.server_conf.protocol {
@@ -462,24 +462,27 @@ impl MailBackend for ImapType {
};
Ok(Box::pin(async move {
debug!(has_idle);
- let main_conn2 = main_conn.clone();
- let timeout_dur = uid_store.timeout;
- let kit = ImapWatchKit {
- conn,
- main_conn,
- uid_store,
- };
- if let Err(err) = if has_idle {
- idle(kit).await
+ while let Err(err) = if has_idle {
+ idle(ImapWatchKit {
+ conn: ImapConnection::new_connection(&server_conf, uid_store.clone()),
+ main_conn: main_conn.clone(),
+ uid_store: uid_store.clone(),
+ })
+ .await
} else {
- poll_with_examine(kit).await
+ poll_with_examine(ImapWatchKit {
+ conn: ImapConnection::new_connection(&server_conf, uid_store.clone()),
+ main_conn: main_conn.clone(),
+ uid_store: uid_store.clone(),
+ })
+ .await
} {
- let mut main_conn = timeout(timeout_dur, main_conn2.lock()).await?;
+ let mut main_conn_lck = timeout(uid_store.timeout, main_conn.lock()).await?;
if err.kind.is_network() {
- main_conn.uid_store.is_online.lock().unwrap().1 = Err(err.clone());
+ uid_store.is_online.lock().unwrap().1 = Err(err.clone());
}
debug!("failure: {}", err.to_string());
- match timeout(timeout_dur, main_conn.connect())
+ match timeout(uid_store.timeout, main_conn_lck.connect())
.await
.and_then(|res| res)
{
@@ -488,10 +491,11 @@ impl MailBackend for ImapType {
}
Ok(()) => {
debug!("reconnect attempt succesful");
+ continue;
}
}
- let account_hash = main_conn.uid_store.account_hash;
- main_conn.add_refresh_event(RefreshEvent {
+ let account_hash = uid_store.account_hash;
+ main_conn_lck.add_refresh_event(RefreshEvent {
account_hash,
mailbox_hash: 0,
kind: RefreshEventKind::Failure(err.clone()),
diff --git a/melib/src/backends/imap/watch.rs b/melib/src/backends/imap/watch.rs
index 07cf061c..7b6f09ed 100644
--- a/melib/src/backends/imap/watch.rs
+++ b/melib/src/backends/imap/watch.rs
@@ -113,30 +113,35 @@ pub async fn idle(kit: ImapWatchKit) -> Result<()> {
};
conn.send_command(b"IDLE").await?;
let mut blockn = ImapBlockingConnection::from(conn);
- let mut beat = std::time::Instant::now();
let mut watch = std::time::Instant::now();
- /* duration interval before IMAP timeouts */
- const _35_MINS: std::time::Duration = std::time::Duration::from_secs(35 * 60);
/* duration interval to send heartbeat */
- const _26_MINS: std::time::Duration = std::time::Duration::from_secs(26 * 60);
+ const _10_MINS: std::time::Duration = std::time::Duration::from_secs(10 * 60);
/* duration interval to check other mailboxes for changes */
const _5_MINS: std::time::Duration = std::time::Duration::from_secs(5 * 60);
- while let Some(line) = timeout(Some(_35_MINS), blockn.as_stream()).await? {
+ loop {
+ let line = match timeout(Some(_10_MINS), blockn.as_stream()).await {
+ Ok(Some(line)) => line,
+ Ok(None) => {
+ debug!("IDLE connection dropped: {:?}", &blockn.err());
+ blockn.conn.connect().await?;
+ let mut main_conn_lck = timeout(uid_store.timeout, main_conn.lock()).await?;
+ main_conn_lck.connect().await?;
+ continue;
+ }
+ Err(_) => {
+ /* Timeout */
+ blockn.conn.send_raw(b"DONE").await?;
+ blockn
+ .conn
+ .read_response(&mut response, RequiredResponses::empty())
+ .await?;
+ blockn.conn.send_command(b"IDLE").await?;
+ let mut main_conn_lck = timeout(uid_store.timeout, main_conn.lock()).await?;
+ main_conn_lck.connect().await?;
+ continue;
+ }
+ };
let now = std::time::Instant::now();
- if now.duration_since(beat) >= _26_MINS {
- let mut main_conn_lck = timeout(uid_store.timeout, main_conn.lock()).await?;
- blockn.conn.send_raw(b"DONE").await?;
- blockn
- .conn
- .read_response(&mut response, RequiredResponses::empty())
- .await?;
- blockn.conn.send_command(b"IDLE").await?;
- main_conn_lck.send_command(b"NOOP").await?;
- main_conn_lck
- .read_response(&mut response, RequiredResponses::empty())
- .await?;
- beat = now;
- }
if now.duration_since(watch) >= _5_MINS {
/* Time to poll all inboxes */
let mut conn = timeout(uid_store.timeout, main_conn.lock()).await?;
@@ -184,11 +189,6 @@ pub async fn idle(kit: ImapWatchKit) -> Result<()> {
blockn.conn.send_command(b"IDLE").await?;
}
}
- debug!("IDLE connection dropped");
- Err(blockn
- .err()
- .unwrap_or(MeliError::new("Unknown reason.").set_kind(crate::error::ErrorKind::Network))
- .set_summary("IDLE connection dropped".to_string()))
}
pub async fn examine_updates(