melib/imap: perform reconnect on IDLE failure
parent
670675edcc
commit
17a4ccdcbc
|
@ -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,
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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)))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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…
Reference in New Issue