mirror of
https://github.com/chatmail/core.git
synced 2026-09-22 13:01:21 +03:00
fix: prevent transport de-synchronization because of early fetch cancellation
Came across this while investigating more test_transport_synchronization flakiness, sometimes missing TransportsModified events or getting a missing configured_addr. The underlying problem was that stopping IO was triggered immediately during receiving sync messages, potentially *canceling* the processing of the sync message, effectively de-syncing the device's view on transports.
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
use std::cmp;
|
||||
use std::future::Future;
|
||||
use std::num::NonZeroUsize;
|
||||
use std::pin::Pin;
|
||||
use std::sync::atomic::Ordering;
|
||||
|
||||
use anyhow::{Context as _, Error, Result, bail};
|
||||
use async_channel::{self as channel, Receiver, Sender};
|
||||
@@ -411,6 +414,12 @@ async fn inbox_loop(
|
||||
.await;
|
||||
}
|
||||
|
||||
/// Same as `context.restart_io_if_running()`, but `Box::pin`ed and with a `+ Send` bound
|
||||
/// to break the async type cycle with the IMAP loop it restarts.
|
||||
fn restart_io_if_running_boxed(context: Context) -> Pin<Box<dyn Future<Output = ()> + Send>> {
|
||||
Box::pin(async move { context.restart_io_if_running().await })
|
||||
}
|
||||
|
||||
async fn inbox_fetch_idle(ctx: &Context, imap: &mut Imap, mut session: Session) -> Result<Session> {
|
||||
let transport_id = session.transport_id();
|
||||
|
||||
@@ -496,6 +505,12 @@ async fn fetch_idle(ctx: &Context, connection: &mut Imap, mut session: Session)
|
||||
.await
|
||||
.context("download_msgs")?;
|
||||
|
||||
if ctx.restart_io_after_fetch.swap(false, Ordering::Relaxed) {
|
||||
// Restarting IO cancels the IMAP loop.
|
||||
// Therefore, we only restart when we're anyways about to go IDLE.
|
||||
task::spawn(restart_io_if_running_boxed(ctx.clone()));
|
||||
}
|
||||
|
||||
connection.connectivity.set_idle(ctx);
|
||||
|
||||
ctx.emit_event(EventType::ImapInboxIdle);
|
||||
|
||||
Reference in New Issue
Block a user