Browse Source

melib/imap: perform reconnect on IDLE failure

tags/alpha-0.6.2
Manos Pitsidianakis 1 month ago
parent
commit
17a4ccdcbc
WARNING! Although there is a key with this ID in the database it does not verify this commit! This commit is SUSPICIOUS. GPG Key ID: 73627C2F690DF710
5 changed files with 45 additions and 22 deletions
  1. +11
    -0
      melib/src/backends/imap.rs
  2. +6
    -6
      melib/src/backends/imap/connection.rs
  3. +4
    -2
      melib/src/backends/imap/watch.rs
  4. +3
    -1
      melib/src/error.rs
  5. +21
    -13
      src/conf/accounts.rs

+ 11
- 0
melib/src/backends/imap.rs View File

@ -479,6 +479,17 @@ impl MailBackend for ImapType {
main_conn.uid_store.is_online.lock().unwrap().1 = Err(err.clone());
}
debug!("failure: {}", err.to_string());
match timeout(timeout_dur, main_conn.connect())
.await
.and_then(|res| res)
{
Err(err2) => {
debug!("reconnect attempt failed: {}", err2.to_string());
}
Ok(()) => {
debug!("reconnect attempt succesful");
}
}
let account_hash = main_conn.uid_store.account_hash;
main_conn.add_refresh_event(RefreshEvent {
account_hash,

+ 6
- 6
melib/src/backends/imap/connection.rs View File

@ -984,7 +984,7 @@ pub struct ImapBlockingConnection {
result: Vec<u8>,
prev_res_length: usize,
pub conn: ImapConnection,
err: Option<String>,
err: Option<MeliError>,
}
impl From<ImapConnection> for ImapBlockingConnection {
@ -1004,8 +1004,8 @@ impl ImapBlockingConnection {
self.conn
}
pub fn err(&self) -> Option<&str> {
self.err.as_deref()
pub fn err(&mut self) -> Option<MeliError> {
self.err.take()
}
pub fn as_stream<'a>(&'a mut self) -> impl Future<Output = Option<Vec<u8>>> + 'a {
@ -1056,10 +1056,10 @@ async fn read(
}
*prev_failure = None;
}
Err(e) => {
Err(_err) => {
debug!(&conn.stream);
debug!(&e);
*err = Some(e.to_string());
debug!(&_err);
*err = Some(Into::<MeliError>::into(_err).set_kind(crate::error::ErrorKind::Network));
*break_flag = true;
*prev_failure = Some(Instant::now());
}

+ 4
- 2
melib/src/backends/imap/watch.rs View File

@ -185,8 +185,10 @@ pub async fn idle(kit: ImapWatchKit) -> Result<()> {
}
}
debug!("IDLE connection dropped");
let err: &str = blockn.err().unwrap_or("Unknown reason.");
Err(MeliError::new(format!("IDLE connection dropped: {}", err)))
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(

+ 3
- 1
melib/src/error.rs View File

@ -205,7 +205,9 @@ impl Error for MeliError {
impl From<io::Error> for MeliError {
#[inline]
fn from(kind: io::Error) -> MeliError {
MeliError::new(kind.to_string()).set_source(Some(Arc::new(kind)))
MeliError::new(kind.to_string())
.set_summary(format!("{:?}", kind.kind()))
.set_source(Some(Arc::new(kind)))
}
}

+ 21
- 13
src/conf/accounts.rs View File

@ -1355,24 +1355,19 @@ impl Account {
let mut timeout = false;
let mut drain: SmallVec<[std::time::Instant; 16]> = SmallVec::new();
const ONLINE_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(30);
for (_instant, j) in self
for (_instant, _) in self
.active_job_instants
.range(..std::time::Instant::now() - ONLINE_TIMEOUT)
{
if self.active_jobs.contains_key(j) {
debug!("timeout for {} {:?}", j, self.active_jobs[j]);
let req = self.active_jobs.remove(j).unwrap();
self.sender
.send(ThreadEvent::UIEvent(UIEvent::StatusEvent(
StatusEvent::JobCanceled(*j),
)))
.unwrap();
timeout |= !req.is_watch();
}
drain.push(*_instant);
}
for j in drain {
self.active_job_instants.remove(&j);
for inst in drain {
if let Some(j) = self.active_job_instants.remove(&inst) {
if let Some(req) = self.cancel_job(j) {
debug!("timeout for {} {:?}", j, &req);
timeout |= !req.is_watch();
}
}
}
if self.is_online.is_err()
&& self
@ -2009,6 +2004,19 @@ impl Account {
)))
.unwrap();
}
pub fn cancel_job(&mut self, job_id: JobId) -> Option<JobRequest> {
if let Some(req) = self.active_jobs.remove(&job_id) {
self.sender
.send(ThreadEvent::UIEvent(UIEvent::StatusEvent(
StatusEvent::JobCanceled(job_id),
)))
.unwrap();
Some(req)
} else {
None
}
}
}
impl Index<&MailboxHash> for Account {

Loading…
Cancel
Save