Skip to content

feat: improve logging around IMAP IDLE #6485

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion python/tests/test_1_online.py
Original file line number Diff line number Diff line change
Expand Up @@ -1983,7 +1983,7 @@ def test_fetch_deleted_msg(acfactory, lp):
if ev.name == "DC_EVENT_MSGS_CHANGED":
pytest.fail("A deleted message was shown to the user")

if ev.name == "DC_EVENT_INFO" and "INBOX: Idle entering wait-on-remote state" in ev.data2:
if ev.name == "DC_EVENT_INFO" and 'IDLE entering wait-on-remote state in folder "INBOX".' in ev.data2:
break # DC is done with reading messages


Expand Down
30 changes: 19 additions & 11 deletions src/imap/idle.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::time::Duration;

use anyhow::{bail, Context as _, Result};
use anyhow::{Context as _, Result};
use async_channel::Receiver;
use async_imap::extensions::idle::IdleResponse;
use futures_lite::FutureExt;
Expand Down Expand Up @@ -38,18 +38,23 @@ impl Session {
}

if self.new_mail {
info!(
context,
"Skipping IDLE in {folder:?} because there may be new mail."
);
return Ok(self);
}

if let Ok(()) = idle_interrupt_receiver.try_recv() {
info!(context, "skip idle, got interrupt");
info!(context, "Skip IDLE in {folder:?} because we got interrupt.");
return Ok(self);
}

let mut handle = self.inner.idle();
if let Err(err) = handle.init().await {
bail!("IMAP IDLE protocol failed to init/complete: {}", err);
}
handle
.init()
.await
.with_context(|| format!("IMAP IDLE protocol failed to init in folder {folder:?}"))?;

// At this point IDLE command was sent and we received a "+ idling" response. We will now
// read from the stream without getting any data for up to `IDLE_TIMEOUT`. If we don't
Expand All @@ -63,7 +68,10 @@ impl Session {
Interrupt,
}

info!(context, "{folder}: Idle entering wait-on-remote state");
info!(
context,
"IDLE entering wait-on-remote state in folder {folder:?}."
);
let fut = idle_wait.map(|ev| ev.map(Event::IdleResponse)).race(async {
idle_interrupt_receiver.recv().await.ok();

Expand All @@ -75,19 +83,19 @@ impl Session {

match fut.await {
Ok(Event::IdleResponse(IdleResponse::NewData(x))) => {
info!(context, "{folder}: Idle has NewData {:?}", x);
info!(context, "{folder:?}: Idle has NewData {x:?}");
}
Ok(Event::IdleResponse(IdleResponse::Timeout)) => {
info!(context, "{folder}: Idle-wait timeout or interruption");
info!(context, "{folder:?}: Idle-wait timeout or interruption.");
}
Ok(Event::IdleResponse(IdleResponse::ManualInterrupt)) => {
info!(context, "{folder}: Idle wait was interrupted manually");
info!(context, "{folder:?}: Idle wait was interrupted manually.");
}
Ok(Event::Interrupt) => {
info!(context, "{folder}: Idle wait was interrupted");
info!(context, "{folder:?}: Idle wait was interrupted.");
}
Err(err) => {
warn!(context, "{folder}: Idle wait errored: {err:?}");
warn!(context, "{folder:?}: Idle wait errored: {err:?}.");
}
}

Expand Down
5 changes: 4 additions & 1 deletion src/scheduler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -671,7 +671,10 @@ async fn fetch_idle(
return Ok(session);
}

info!(ctx, "IMAP session supports IDLE, using it.");
info!(
ctx,
"IMAP session in folder {watch_folder:?} supports IDLE, using it."
);
let session = session
.idle(
ctx,
Expand Down
Loading