Do the background fetch in the background

This commit is contained in:
Hocuri
2026-08-07 17:12:51 +02:00
parent 1247d5da36
commit 95f9397e48
5 changed files with 80 additions and 41 deletions

View File

@@ -515,6 +515,7 @@ pub unsafe extern "C" fn dc_event_get_id(event: *mut dc_event_t) -> libc::c_int
EventType::WebxdcRealtimeData { .. } => 2150,
EventType::WebxdcRealtimeAdvertisementReceived { .. } => 2151,
EventType::AccountsBackgroundFetchDone => 2200,
EventType::AccountsBackgroundFetchTimedOut => 2201,
EventType::ChatlistChanged => 2300,
EventType::ChatlistItemChanged { .. } => 2301,
EventType::AccountsChanged => 2302,
@@ -557,6 +558,7 @@ pub unsafe extern "C" fn dc_event_get_data1_int(event: *mut dc_event_t) -> libc:
| EventType::IncomingMsgBunch
| EventType::ErrorSelfNotInGroup(_)
| EventType::AccountsBackgroundFetchDone
| EventType::AccountsBackgroundFetchTimedOut
| EventType::ChatlistChanged
| EventType::AccountsChanged
| EventType::AccountsItemChanged
@@ -638,6 +640,7 @@ pub unsafe extern "C" fn dc_event_get_data2_int(event: *mut dc_event_t) -> libc:
| EventType::IncomingMsgBunch
| EventType::SelfavatarChanged
| EventType::AccountsBackgroundFetchDone
| EventType::AccountsBackgroundFetchTimedOut
| EventType::ChatlistChanged
| EventType::ChatlistItemChanged { .. }
| EventType::AccountsChanged
@@ -745,6 +748,7 @@ pub unsafe extern "C" fn dc_event_get_data2_str(event: *mut dc_event_t) -> *mut
| EventType::WebxdcStatusUpdate { .. }
| EventType::WebxdcInstanceDeleted { .. }
| EventType::AccountsBackgroundFetchDone
| EventType::AccountsBackgroundFetchTimedOut
| EventType::ChatEphemeralTimerModified { .. }
| EventType::ChatDeleted { .. }
| EventType::IncomingMsgBunch
@@ -4774,12 +4778,8 @@ pub unsafe extern "C" fn dc_accounts_background_fetch(
}
let accounts = unsafe { &*accounts };
let background_fetch_future = {
let lock = block_on(accounts.read());
lock.background_fetch(Duration::from_secs(timeout_in_seconds))
};
// At this point account manager is not locked anymore.
block_on(background_fetch_future);
let lock = block_on(accounts.read());
lock.background_fetch(Duration::from_secs(timeout_in_seconds));
1
}

View File

@@ -283,12 +283,8 @@ impl CommandApi {
/// Process all events until you get this one and you can safely return to the background
/// without forgetting to create notifications caused by timing race conditions.
async fn background_fetch(&self, timeout_in_seconds: f64) -> Result<()> {
let future = {
let lock = self.accounts.read().await;
lock.background_fetch(std::time::Duration::from_secs_f64(timeout_in_seconds))
};
// At this point account manager is not locked anymore.
future.await;
let lock = self.accounts.read().await;
lock.background_fetch(std::time::Duration::from_secs_f64(timeout_in_seconds));
Ok(())
}

View File

@@ -30,37 +30,55 @@ pub enum EventType {
///
/// This event should *not* be reported to the end-user using a popup or something like
/// that.
Info { msg: String },
Info {
msg: String,
},
/// Emitted when SMTP connection is established and login was successful.
SmtpConnected { msg: String },
SmtpConnected {
msg: String,
},
/// Emitted when IMAP connection is established and login was successful.
ImapConnected { msg: String },
ImapConnected {
msg: String,
},
/// Emitted when a message was successfully sent to the SMTP server.
SmtpMessageSent { msg: String },
SmtpMessageSent {
msg: String,
},
/// Emitted when an IMAP message has been marked as deleted
ImapMessageDeleted { msg: String },
ImapMessageDeleted {
msg: String,
},
/// Emitted when an IMAP message has been moved
ImapMessageMoved { msg: String },
ImapMessageMoved {
msg: String,
},
/// Emitted before going into IDLE on the Inbox folder.
ImapInboxIdle,
/// Emitted when an new file in the $BLOBDIR was created
NewBlobFile { file: String },
NewBlobFile {
file: String,
},
/// Emitted when an file in the $BLOBDIR was deleted
DeletedBlobFile { file: String },
DeletedBlobFile {
file: String,
},
/// The library-user should write a warning string to the log.
///
/// This event should *not* be reported to the end-user using a popup or something like
/// that.
Warning { msg: String },
Warning {
msg: String,
},
/// The library-user should report an error to the end-user.
///
@@ -72,14 +90,18 @@ pub enum EventType {
/// it might be better to delay showing these events until the function has really
/// failed (returned false). It should be sufficient to report only the *last* error
/// in a message box then.
Error { msg: String },
Error {
msg: String,
},
/// An action cannot be performed because the user is not in the group.
/// Reported eg. after a call to
/// setChatName(), setChatProfileImage(),
/// addContactToChat(), removeContactFromChat(),
/// and messages sending functions.
ErrorSelfNotInGroup { msg: String },
ErrorSelfNotInGroup {
msg: String,
},
/// Messages or chats changed. One or more messages or chats changed for various
/// reasons in the database:
@@ -168,7 +190,9 @@ pub enum EventType {
/// Messages were seen or noticed.
/// chat id is always set.
#[serde(rename_all = "camelCase")]
MsgsNoticed { chat_id: u32 },
MsgsNoticed {
chat_id: u32,
},
/// A single message is sent successfully. State changed from DC_STATE_OUT_PENDING to
/// DC_STATE_OUT_DELIVERED, see `Message.state`.
@@ -243,7 +267,9 @@ pub enum EventType {
/// This event does not include ephemeral timer modification, which
/// is a separate event.
#[serde(rename_all = "camelCase")]
ChatModified { chat_id: u32 },
ChatModified {
chat_id: u32,
},
/// Chat ephemeral timer changed.
#[serde(rename_all = "camelCase")]
@@ -304,7 +330,9 @@ pub enum EventType {
///
/// @param data2 0
#[serde(rename_all = "camelCase")]
ImexFileWritten { path: String },
ImexFileWritten {
path: String,
},
/// Progress event sent when SecureJoin protocol has finished
/// from the view of the inviter (Alice, the person who shows the QR code).
@@ -482,6 +510,9 @@ pub enum EventType {
/// synchronization messages arrives,
/// but not when the UI modifies the transport list by itself.
TransportsModified,
// TODO documentation
AccountsBackgroundFetchTimedOut,
}
impl From<CoreEventType> for EventType {
@@ -675,6 +706,8 @@ impl From<CoreEventType> for EventType {
},
CoreEventType::TransportsModified => TransportsModified,
CoreEventType::AccountsBackgroundFetchTimedOut => AccountsBackgroundFetchTimedOut,
#[allow(unreachable_patterns)]
#[cfg(test)]
_ => unreachable!("This is just to silence a rust_analyzer false-positive"),

View File

@@ -452,6 +452,10 @@ impl Accounts {
)
.await
{
events.emit(Event {
id: 0,
typ: EventType::AccountsBackgroundFetchTimedOut,
});
events.emit(Event {
id: 0,
typ: EventType::Warning("Background fetch timed out.".to_string()),
@@ -461,14 +465,16 @@ impl Accounts {
account_id = 0,
"Background fetch timed out."
);
} else {
events.emit(Event {
id: 0,
typ: EventType::AccountsBackgroundFetchDone,
});
}
events.emit(Event {
id: 0,
typ: EventType::AccountsBackgroundFetchDone,
});
(*interrupt_sender.lock()) = None;
}
// TODO adapt all the documentation
/// Performs a background fetch for all accounts in parallel with a timeout.
///
/// Ongoing background fetch can also be cancelled manually
@@ -482,10 +488,7 @@ impl Accounts {
///
/// Returns a future that resolves when background fetch is done,
/// but does not capture `&self`.
pub fn background_fetch(
&self,
timeout: std::time::Duration,
) -> impl Future<Output = ()> + use<> {
pub fn background_fetch(&self, timeout: std::time::Duration) {
let accounts: Vec<Context> = self.accounts.values().cloned().collect();
let events = self.events.clone();
let (sender, receiver) = async_channel::bounded(1);
@@ -500,13 +503,17 @@ impl Accounts {
Some(receiver)
}
};
Self::background_fetch_with_timeout(
accounts,
events,
timeout,
self.background_fetch_interrupt_sender.clone(),
receiver,
)
let background_fetch_interrupt_sender = self.background_fetch_interrupt_sender.clone();
tokio::task::spawn(async move {
Self::background_fetch_with_timeout(
accounts,
events,
timeout,
background_fetch_interrupt_sender,
receiver,
)
.await
});
}
/// Interrupts ongoing background_fetch() call,

View File

@@ -447,4 +447,7 @@ pub enum EventType {
/// Number of events skipped.
n: u64,
},
// TODO documentation
AccountsBackgroundFetchTimedOut,
}