shortcut fetch/idle on mvbox/sentbox if we don't know the folder and prevent busy-looping

This commit is contained in:
holger krekel
2019-11-12 13:27:38 +01:00
parent 5293ea70ae
commit 0405c945e2
2 changed files with 45 additions and 25 deletions

View File

@@ -746,10 +746,13 @@ impl Imap {
pub fn idle(&self, context: &Context) {
task::block_on(async move {
if self.config.read().await.selected_folder.is_none() {
// this probably means that we are in teardown
// in any case we can't perform any idling
return;
}
if !self.config.read().await.can_idle {
self.fake_idle(context).await;
self.fake_idle(context, true).await;
return;
}
@@ -765,7 +768,7 @@ impl Imap {
"idle select_folder failed {:?}",
watch_folder.as_ref()
);
self.fake_idle(context).await;
self.fake_idle(context, true).await;
return;
}
}
@@ -836,7 +839,7 @@ impl Imap {
});
}
async fn fake_idle(&self, context: &Context) {
pub(crate) async fn fake_idle(&self, context: &Context, use_network: bool) {
// Idle using timeouts. This is also needed if we're not yet configured -
// in this case, we're waiting for a configure job
let fake_idle_start_time = SystemTime::now();
@@ -846,13 +849,20 @@ impl Imap {
task::block_on(async move {
let interrupt = stop_token::StopSource::new();
// TODO: More flexible interval
let interval = async_std::stream::interval(Duration::from_secs(10));
// we use 1000 minutes if we are told to not try network
// which can happen because the watch_folder is not defined
// but clients are still calling us in a loop.
// if we are to use network, we check every minute if there
// is new mail -- TODO: make this more flexible
let secs = if use_network { 60 } else { 60000 };
let interval = async_std::stream::interval(Duration::from_secs(secs));
let mut interrupt_interval = interrupt.stop_token().stop_stream(interval);
*self.interrupt.lock().await = Some(interrupt);
while let Some(_) = interrupt_interval.next().await {
// check if we want to finish fake-idling.
if !use_network {
continue;
}
if !self.is_connected().await {
// try to connect with proper login params
// (setup_handle_if_needed might not know about them if we
@@ -1154,13 +1164,6 @@ impl Imap {
.list_folders(session, context)
.await
.expect("no folders found");
let delimiter = self.config.read().await.imap_delimiter;
let fallback_folder = format!("INBOX{}DeltaChat", delimiter);
let mut mvbox_folder = folders
.iter()
.find(|folder| folder.name() == "DeltaChat" || folder.name() == fallback_folder)
.map(|n| n.name().to_string());
let sentbox_folder =
folders
@@ -1169,6 +1172,15 @@ impl Imap {
FolderMeaning::SentObjects => true,
_ => false,
});
info!(context, "sentbox folder is {:?}", sentbox_folder);
let delimiter = self.config.read().await.imap_delimiter;
let fallback_folder = format!("INBOX{}DeltaChat", delimiter);
let mut mvbox_folder = folders
.iter()
.find(|folder| folder.name() == "DeltaChat" || folder.name() == fallback_folder)
.map(|n| n.name().to_string());
if mvbox_folder.is_none() && 0 != (flags as usize & DC_CREATE_MVBOX) {
info!(context, "Creating MVBOX-folder \"DeltaChat\"...",);

View File

@@ -110,9 +110,14 @@ impl JobThread {
if async_std::task::block_on(async move { self.imap.is_connected().await }) {
return true;
}
let watch_folder_name = match context.sql.get_raw_config(context, self.folder_config_name) {
Some(name) => name,
None => {
return false;
}
};
let mut ret_connected = dc_connect_to_configured_imap(context, &self.imap) != 0;
let ret_connected = dc_connect_to_configured_imap(context, &self.imap) != 0;
if ret_connected {
if context
.sql
@@ -123,12 +128,7 @@ impl JobThread {
self.imap.configure_folders(context, 0x1);
}
if let Some(mvbox_name) = context.sql.get_raw_config(context, self.folder_config_name) {
self.imap.set_watch_folder(mvbox_name);
} else {
self.imap.disconnect(context);
ret_connected = false;
}
self.imap.set_watch_folder(watch_folder_name);
}
ret_connected
@@ -170,10 +170,18 @@ impl JobThread {
}
}
self.connect_to_imap(context);
info!(context, "{}-IDLE started...", self.name,);
self.imap.idle(context);
info!(context, "{}-IDLE ended.", self.name);
if self.connect_to_imap(context) {
info!(context, "{}-IDLE started...", self.name,);
self.imap.idle(context);
info!(context, "{}-IDLE ended.", self.name);
} else {
// It's probably wrong that the thread even runs
// but let's call fake_idle and tell it to not try network at all.
// (once we move to rust-managed threads this problem goes away)
info!(context, "{}-IDLE not connected, fake-idling", self.name);
async_std::task::block_on(async move { self.imap.fake_idle(context, false).await });
info!(context, "{}-IDLE fake-idling finished", self.name);
}
self.state.0.lock().unwrap().using_handle = false;
}