mirror of
https://github.com/chatmail/core.git
synced 2026-04-17 21:46:35 +03:00
make setup_handle_if_needed async, call it ahead of select_folder and fetch_new_messages (renamed from fetch_from_single_folder), and be more eager triggering reconnect on error conditions
This commit is contained in:
@@ -201,8 +201,7 @@ impl Imap {
|
||||
self.should_reconnect.store(true, Ordering::Relaxed)
|
||||
}
|
||||
|
||||
fn setup_handle_if_needed(&self, context: &Context) -> Result<()> {
|
||||
task::block_on(async move {
|
||||
async fn setup_handle_if_needed(&self, context: &Context) -> Result<()> {
|
||||
if self.config.read().await.imap_server.is_empty() {
|
||||
return Err(Error::InTeardown);
|
||||
}
|
||||
@@ -254,9 +253,7 @@ impl Imap {
|
||||
if (server_flags & DC_LP_AUTH_OAUTH2) != 0 {
|
||||
let addr: &str = config.addr.as_ref();
|
||||
|
||||
if let Some(token) =
|
||||
dc_get_oauth2_access_token(context, addr, imap_pw, true)
|
||||
{
|
||||
if let Some(token) = dc_get_oauth2_access_token(context, addr, imap_pw, true) {
|
||||
let auth = OAuth2 {
|
||||
user: imap_user.into(),
|
||||
access_token: token,
|
||||
@@ -295,8 +292,7 @@ impl Imap {
|
||||
}
|
||||
Err((err, _)) => {
|
||||
let imap_user = self.config.read().await.imap_user.to_owned();
|
||||
let message =
|
||||
context.stock_string_repl_str(StockMessage::CannotLogin, &imap_user);
|
||||
let message = context.stock_string_repl_str(StockMessage::CannotLogin, &imap_user);
|
||||
|
||||
emit_event!(
|
||||
context,
|
||||
@@ -306,7 +302,6 @@ impl Imap {
|
||||
Err(Error::LoginFailed(format!("cannot login as {}", imap_user)))
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
async fn unsetup_handle(&self, context: &Context) {
|
||||
@@ -387,7 +382,7 @@ impl Imap {
|
||||
config.server_flags = server_flags;
|
||||
}
|
||||
|
||||
if let Err(err) = self.setup_handle_if_needed(context) {
|
||||
if let Err(err) = self.setup_handle_if_needed(context).await {
|
||||
warn!(context, "failed to setup imap handle: {}", err);
|
||||
self.free_connect_params().await;
|
||||
return false;
|
||||
@@ -449,10 +444,9 @@ impl Imap {
|
||||
// probably shutdown
|
||||
return Err(Error::InTeardown);
|
||||
}
|
||||
while self
|
||||
.fetch_from_single_folder(context, &watch_folder)
|
||||
.await?
|
||||
{
|
||||
self.setup_handle_if_needed(context).await?;
|
||||
|
||||
while self.fetch_new_messages(context, &watch_folder).await? {
|
||||
// We fetch until no more new messages are there.
|
||||
}
|
||||
Ok(())
|
||||
@@ -560,7 +554,7 @@ impl Imap {
|
||||
})
|
||||
}
|
||||
|
||||
async fn fetch_from_single_folder<S: AsRef<str>>(
|
||||
async fn fetch_new_messages<S: AsRef<str>>(
|
||||
&self,
|
||||
context: &Context,
|
||||
folder: S,
|
||||
@@ -593,9 +587,11 @@ impl Imap {
|
||||
for msg in &list {
|
||||
let cur_uid = msg.uid.unwrap_or_default();
|
||||
if cur_uid <= last_seen_uid {
|
||||
warn!(
|
||||
// seems that at least dovecot sends the last available UID
|
||||
// even if we asked for higher UID+N:*
|
||||
info!(
|
||||
context,
|
||||
"unexpected uid {}, last seen was {}", cur_uid, last_seen_uid
|
||||
"fetch_new_messages: ignoring uid {}, last seen was {}", cur_uid, last_seen_uid
|
||||
);
|
||||
continue;
|
||||
}
|
||||
@@ -740,7 +736,7 @@ impl Imap {
|
||||
return Err(Error::IdleAbilityMissing);
|
||||
}
|
||||
|
||||
self.setup_handle_if_needed(context)?;
|
||||
self.setup_handle_if_needed(context).await?;
|
||||
|
||||
self.select_folder(context, watch_folder.clone()).await?;
|
||||
|
||||
@@ -886,9 +882,9 @@ impl Imap {
|
||||
// will not find any new.
|
||||
|
||||
if let Some(ref watch_folder) = watch_folder {
|
||||
match self.fetch_from_single_folder(context, watch_folder).await {
|
||||
match self.fetch_new_messages(context, watch_folder).await {
|
||||
Ok(res) => {
|
||||
info!(context, "fetch_from_single_folder returned {:?}", res);
|
||||
info!(context, "fetch_new_messages returned {:?}", res);
|
||||
if res {
|
||||
break;
|
||||
}
|
||||
@@ -1322,13 +1318,17 @@ impl Imap {
|
||||
task::block_on(async move {
|
||||
info!(context, "emptying folder {}", folder);
|
||||
|
||||
// we want to report all error to the user
|
||||
// (no retry should be attempted)
|
||||
if folder.is_empty() {
|
||||
error!(context, "cannot perform empty, folder not set");
|
||||
return;
|
||||
}
|
||||
if let Err(err) = self.setup_handle_if_needed(context).await {
|
||||
error!(context, "could not setup imap connection: {:?}", err);
|
||||
return;
|
||||
}
|
||||
if let Err(err) = self.select_folder(context, Some(&folder)).await {
|
||||
// we want to report all error to the user
|
||||
// (no retry should be attempted)
|
||||
error!(
|
||||
context,
|
||||
"Could not select {} for expunging: {:?}", folder, err
|
||||
|
||||
@@ -34,6 +34,7 @@ impl Imap {
|
||||
let mut cfg = self.config.write().await;
|
||||
cfg.selected_folder = None;
|
||||
cfg.selected_folder_needs_expunge = false;
|
||||
self.trigger_reconnect();
|
||||
return Err(Error::NoSession);
|
||||
}
|
||||
|
||||
@@ -61,6 +62,7 @@ impl Imap {
|
||||
info!(context, "close/expunge succeeded");
|
||||
}
|
||||
Err(err) => {
|
||||
self.trigger_reconnect();
|
||||
return Err(Error::CloseExpungeFailed(err));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user