From cde587fefa9158413b732402c000b7aba7ed0bcd Mon Sep 17 00:00:00 2001 From: Alexander Krotov Date: Thu, 16 Jul 2020 03:59:05 +0300 Subject: [PATCH] idle: drain unsolicited response channel This prevents multiple unsolicited messages from skipping multiple IDLEs. Also skip IDLE only if an EXISTS message was received. --- src/imap/idle.rs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/imap/idle.rs b/src/imap/idle.rs index 17966457f..17b53a0f7 100644 --- a/src/imap/idle.rs +++ b/src/imap/idle.rs @@ -1,6 +1,7 @@ use super::Imap; use async_imap::extensions::idle::IdleResponse; +use async_imap::types::UnsolicitedResponse; use async_std::prelude::*; use std::time::{Duration, SystemTime}; @@ -53,13 +54,22 @@ impl Imap { if let Some(session) = self.session.take() { // if we have unsolicited responses we directly return - if let Ok(res) = session.unsolicited_responses.try_recv() { - warn!(context, "skip idle, got unsolicited response {:?}", res); + let mut unsolicited_exists = false; + while let Ok(response) = session.unsolicited_responses.try_recv() { + match response { + UnsolicitedResponse::Exists(_) => { + warn!(context, "skip idle, got unsolicited EXISTS {:?}", response); + unsolicited_exists = true; + } + _ => info!(context, "ignoring unsolicited response {:?}", response), + } + } + + if unsolicited_exists { self.session = Some(session); return Ok(info); } - let mut handle = session.idle(); if let Err(err) = handle.init().await { return Err(Error::IdleProtocolFailed(err));