diff --git a/CHANGELOG.md b/CHANGELOG.md index 5212242f2..7ea72ad09 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,8 @@ this affects `dc_get_chat_contacts()`, `dc_get_contacts()` and `dc_get_blocked_contacts()` #3562 - add `internet_access` flag to `dc_msg_get_webxdc_info()` #3516 - `DC_EVENT_WEBXDC_INSTANCE_DELETED` is emitted when a message containing a webxdc gets deleted #3105 +- `DC_EVENT_WEBXDC_BUSY_UPDATING` is emitted when a new update has to be sent by an webxdc #3320 +- `DC_EVENT_WEBXDC_UP_TO_DATE` is emitted when a webxdc has sent all updates #3320 ### Fixes - do not emit notifications for blocked chats #3557 diff --git a/deltachat-ffi/deltachat.h b/deltachat-ffi/deltachat.h index 3d785a71c..970f6a514 100644 --- a/deltachat-ffi/deltachat.h +++ b/deltachat-ffi/deltachat.h @@ -5731,10 +5731,24 @@ void dc_event_unref(dc_event_t* event); * * @param data1 (int) msg_id */ - #define DC_EVENT_WEBXDC_INSTANCE_DELETED 2121 +/** + * Webxdc has some updates that need to be sent + * + * @param data1 (int) msg_id + */ +#define DC_EVENT_WEBXDC_BUSY_UPDATING 2122 + + +/** + * Webxdc has finished sending updates + * + * @param data1 (int) msg_id + */ +#define DC_EVENT_WEBXDC_UP_TO_DATE 2123 + /** * @} */ diff --git a/deltachat-ffi/src/lib.rs b/deltachat-ffi/src/lib.rs index 2f872d6e1..2e7fd40da 100644 --- a/deltachat-ffi/src/lib.rs +++ b/deltachat-ffi/src/lib.rs @@ -505,6 +505,8 @@ pub unsafe extern "C" fn dc_event_get_id(event: *mut dc_event_t) -> libc::c_int EventType::SelfavatarChanged => 2110, EventType::WebxdcStatusUpdate { .. } => 2120, EventType::WebxdcInstanceDeleted { .. } => 2121, + EventType::WebxdcBusyUpdating { .. } => 2022, + EventType::WebxdcUpToDate { .. } => 2023, } } @@ -552,6 +554,8 @@ pub unsafe extern "C" fn dc_event_get_data1_int(event: *mut dc_event_t) -> libc: } EventType::WebxdcStatusUpdate { msg_id, .. } => msg_id.to_u32() as libc::c_int, EventType::WebxdcInstanceDeleted { msg_id, .. } => msg_id.to_u32() as libc::c_int, + EventType::WebxdcBusyUpdating { msg_id } => msg_id.to_u32() as libc::c_int, + EventType::WebxdcUpToDate { msg_id } => msg_id.to_u32() as libc::c_int, } } @@ -584,6 +588,8 @@ pub unsafe extern "C" fn dc_event_get_data2_int(event: *mut dc_event_t) -> libc: | EventType::MsgsNoticed(_) | EventType::ConnectivityChanged | EventType::WebxdcInstanceDeleted { .. } + | EventType::WebxdcBusyUpdating { .. } + | EventType::WebxdcUpToDate { .. } | EventType::SelfavatarChanged => 0, EventType::ChatModified(_) => 0, EventType::MsgsChanged { msg_id, .. } @@ -641,6 +647,8 @@ pub unsafe extern "C" fn dc_event_get_data2_str(event: *mut dc_event_t) -> *mut | EventType::SelfavatarChanged | EventType::WebxdcStatusUpdate { .. } | EventType::WebxdcInstanceDeleted { .. } + | EventType::WebxdcBusyUpdating { .. } + | EventType::WebxdcUpToDate { .. } | EventType::ChatEphemeralTimerModified { .. } => ptr::null_mut(), EventType::ConfigureProgress { comment, .. } => { if let Some(comment) = comment { diff --git a/deltachat-jsonrpc/src/api/events.rs b/deltachat-jsonrpc/src/api/events.rs index 61e1162c9..a4d052c2c 100644 --- a/deltachat-jsonrpc/src/api/events.rs +++ b/deltachat-jsonrpc/src/api/events.rs @@ -61,6 +61,8 @@ pub fn event_to_json_rpc_notification(event: Event) -> Value { status_update_serial, } => (json!(msg_id), json!(status_update_serial)), EventType::WebxdcInstanceDeleted { msg_id } => (json!(msg_id), Value::Null), + EventType::WebxdcBusyUpdating { msg_id } => (json!(msg_id), Value::Null), + EventType::WebxdcUpToDate { msg_id } => (json!(msg_id), Value::Null), }; let id: EventTypeName = event.typ.into(); @@ -103,7 +105,9 @@ pub enum EventTypeName { ConnectivityChanged, SelfavatarChanged, WebxdcStatusUpdate, - WebXdInstanceDeleted, + WebxdcInstanceDeleted, + WebxdcBusyUpdating, + WebxdcUpToDate, } impl From for EventTypeName { @@ -139,7 +143,9 @@ impl From for EventTypeName { EventType::ConnectivityChanged => ConnectivityChanged, EventType::SelfavatarChanged => SelfavatarChanged, EventType::WebxdcStatusUpdate { .. } => WebxdcStatusUpdate, - EventType::WebxdcInstanceDeleted { .. } => WebXdInstanceDeleted, + EventType::WebxdcInstanceDeleted { .. } => WebxdcInstanceDeleted, + EventType::WebxdcBusyUpdating { .. } => WebxdcBusyUpdating, + EventType::WebxdcUpToDate { .. } => WebxdcUpToDate, } } } diff --git a/src/events.rs b/src/events.rs index 29fb039b2..3ed103b9e 100644 --- a/src/events.rs +++ b/src/events.rs @@ -307,4 +307,12 @@ pub enum EventType { WebxdcInstanceDeleted { msg_id: MsgId, }, + + WebxdcBusyUpdating { + msg_id: MsgId, + }, + + WebxdcUpToDate { + msg_id: MsgId, + }, } diff --git a/src/scheduler.rs b/src/scheduler.rs index 069e5dd89..5e5761a87 100644 --- a/src/scheduler.rs +++ b/src/scheduler.rs @@ -332,7 +332,7 @@ async fn smtp_loop(ctx: Context, started: Sender<()>, smtp_handlers: SmtpConnect if !duration_until_can_send.is_zero() { info!( ctx, - "smtp got rate limited, waiting for {} until can send again", + "smtp got rate limited, delaying next try by {}", duration_to_str(duration_until_can_send) ); tokio::time::timeout(duration_until_can_send, async { diff --git a/src/smtp.rs b/src/smtp.rs index a3affdfce..ef1437c7e 100644 --- a/src/smtp.rs +++ b/src/smtp.rs @@ -22,6 +22,7 @@ use crate::mimefactory::MimeFactory; use crate::oauth2::get_oauth2_access_token; use crate::provider::Socket; use crate::sql; +use crate::webxdc::get_busy_webxdc_instances; use crate::{context::Context, scheduler::connectivity::ConnectivityStore}; /// SMTP write and read timeout in seconds. @@ -499,7 +500,15 @@ async fn send_mdns(context: &Context, connection: &mut Smtp) -> Result<()> { pub(crate) async fn send_smtp_messages(context: &Context, connection: &mut Smtp) -> Result<()> { let ratelimited = if context.ratelimit.read().await.can_send() { // add status updates and sync messages to end of sending queue + + let update_needed = get_busy_webxdc_instances(); context.flush_status_updates().await?; + let update_needed_after_sending = get_busy_webxdc_instances(); + + for msg_id in update_needed.difference(&update_needed_after_sending) { + context.emit_event(EventType::WebxdcUpToDate { msg_id: *msg_id }) + } + context.send_sync_msg().await?; false } else { diff --git a/src/webxdc.rs b/src/webxdc.rs index 05fa96875..6777c51f6 100644 --- a/src/webxdc.rs +++ b/src/webxdc.rs @@ -1,5 +1,6 @@ //! # Handle webxdc messages. +use std::collections::HashSet; use std::convert::TryFrom; use std::path::Path; @@ -377,6 +378,10 @@ impl Context { ) .await?; + self.emit_event(EventType::WebxdcBusyUpdating { + msg_id: instance.id, + }); + if send_now { self.sql.insert( "INSERT INTO smtp_status_updates (msg_id, first_serial, last_serial, descr) VALUES(?, ?, ?, ?) @@ -390,7 +395,6 @@ impl Context { } /// Pops one record of queued webxdc status updates. - /// This function exists to make the sqlite statement testable. async fn pop_smtp_status_update( &self, ) -> Result> { @@ -744,6 +748,12 @@ impl Message { } } +/// Returns a hashset of all webxdc instaces which still have updates to send +pub(crate) fn get_busy_webxdc_instances() -> HashSet { + // TODO: add sql statement to find that out + unimplemented!() +} + #[cfg(test)] mod tests { use crate::chat::{