api: add JSON-RPC API is_sending_finished()

This commit is contained in:
link2xt
2026-09-12 14:29:23 +00:00
committed by l
parent 0b2051cda4
commit 44387f5e58
5 changed files with 66 additions and 0 deletions

View File

@@ -2775,6 +2775,15 @@ impl CommandApi {
.map(JsonrpcAppSource::from_core_type),
)
}
/// Returns true if all accounts have empty outgoing message queue.
///
/// This API is intended to be used by UIs
/// to request that operating system does not put the application in background
/// while there are still outgoing messages that are not sent out.
async fn is_sending_finished(&self) -> Result<bool> {
self.accounts.read().await.is_sending_finished().await
}
}
// Helper functions (to prevent code duplication)

View File

@@ -67,3 +67,7 @@ class DeltaChat:
def stop_sending_locations(self) -> None:
"""Stop sending locations to all chats."""
return self.rpc.stop_sending_locations()
def is_sending_finished(self) -> bool:
"""Return true if sending queues of all accounts are empty."""
return self.rpc.is_sending_finished()

View File

@@ -1435,3 +1435,35 @@ def test_large_message(acf, rpcdata) -> None:
assert msg.id == msgs_changed_event.msg_id
snapshot = msg.get_snapshot()
assert snapshot.text == "Hello World, this message is bigger than 5 bytes"
def test_is_sending_finished(dc, acf) -> None:
alice, bob = acf.get_online_accounts(2)
alice_chat_bob = alice.create_chat(bob)
bob_chat_alice = bob.create_chat(alice)
assert dc.is_sending_finished()
alice_chat_bob.send_text("Hello!")
alice.wait_for_event(EventType.SMTP_MESSAGE_SENT)
assert dc.is_sending_finished()
alice.stop_io()
bob.stop_io()
bob_chat_alice.send_text("Hello back!")
alice_chat_bob.send_text("Hello again!")
assert not dc.is_sending_finished()
alice.start_io()
alice.wait_for_event(EventType.SMTP_MESSAGE_SENT)
assert not dc.is_sending_finished()
bob.start_io()
bob.wait_for_event(EventType.SMTP_MESSAGE_SENT)
assert dc.is_sending_finished()

View File

@@ -26,6 +26,7 @@ use crate::events::{Event, EventEmitter, EventType, Events};
use crate::location;
use crate::log::warn;
use crate::push::PushSubscriber;
use crate::smtp;
use crate::stock_str::StockStrings;
/// Account manager, that can handle multiple accounts in a single place.
@@ -509,6 +510,20 @@ impl Accounts {
)
}
/// Returns true if there are no pending messages for sending.
///
/// This is intended to be used by UIs to request not moving the app to background
/// when there are messages left in the queue.
pub async fn is_sending_finished(&self) -> Result<bool> {
let accounts: Vec<Context> = self.accounts.values().cloned().collect();
for account in accounts {
if !smtp::is_queue_empty(&account).await? {
return Ok(false);
}
}
Ok(true)
}
/// Interrupts ongoing background_fetch() call,
/// making it return early.
///

View File

@@ -751,3 +751,9 @@ pub(crate) async fn add_self_recipients(
Ok(())
}
/// Returns true if SMTP queue is empty.
pub(crate) async fn is_queue_empty(context: &Context) -> Result<bool> {
let sending_finished = !context.sql.exists("SELECT COUNT(*) FROM smtp", ()).await?;
Ok(sending_finished)
}