From 0000c09ad3d4485d3eec1a77609e6bf33d6dbe52 Mon Sep 17 00:00:00 2001 From: link2xt Date: Thu, 29 Feb 2024 01:47:30 +0000 Subject: [PATCH] fix(imap): allow maybe_network to interrupt connection ratelimit ratelimit can be exhausted quickly if the network is not available, i.e. if every connection attempt returns "network unreachable" error. When the network becomes available, we want to retry connecting as soon as maybe_network is called without waiting for ratelimiter. --- src/imap.rs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/imap.rs b/src/imap.rs index 4da64b385..df405d1ce 100644 --- a/src/imap.rs +++ b/src/imap.rs @@ -15,7 +15,8 @@ use std::{ use anyhow::{bail, format_err, Context as _, Result}; use async_channel::Receiver; use async_imap::types::{Fetch, Flag, Name, NameAttribute, UnsolicitedResponse}; -use futures::{StreamExt, TryStreamExt}; +use futures::{FutureExt as _, StreamExt, TryStreamExt}; +use futures_lite::FutureExt; use num_traits::FromPrimitive; use ratelimit::Ratelimit; use tokio::sync::RwLock; @@ -331,7 +332,18 @@ impl Imap { "IMAP got rate limited, waiting for {} until can connect", duration_to_str(ratelimit_duration), ); - tokio::time::sleep(ratelimit_duration).await; + let interrupted = async { + tokio::time::sleep(ratelimit_duration).await; + false + } + .race(self.idle_interrupt_receiver.recv().map(|_| true)) + .await; + if interrupted { + info!( + context, + "Connecting to IMAP without waiting for ratelimit due to interrupt." + ); + } } info!(context, "Connecting to IMAP server");