Don't restart the send queue while the client is suspended

The send queue auto-enable listener fires whenever the queue is believed
off and the homeserver is reachable. While the client is suspended this
could re-enable the queue and potentially fall straight back into a re-enable
loop.

Gate the listener on the desired service state so queues are only restarted
when we intend to be running, and nudge the listener on resume so the queue
recovers reliably. The SDK only re-enables queues when client.resume() runs,
which is gated behind clientPausingAndResumingEnabled, so the nudge keeps
recovery uniform across builds rather than depending on the flag.
This commit is contained in:
Stefan Ceriu
2026-06-15 13:13:15 +03:00
parent 02b114d40b
commit 514f2b26fc
@@ -1033,10 +1033,12 @@ class ClientProxy: ClientProxyProtocol {
sendQueueStatusSubject
.combineLatest(homeserverReachabilityPublisher)
.debounce(for: 1.0, scheduler: DispatchQueue.main)
.sink { [client] enabled, reachability in
.sink { [weak self, client] enabled, reachability in
MXLog.info("Send queue status changed to enabled: \(enabled), homeserver reachability: \(reachability)")
if enabled == false, reachability == .reachable {
// Don't restart the send queue unless the client is meant to be running; doing so while
// suspended would generate network activity in the window we paused to keep quiet.
if enabled == false, reachability == .reachable, self?.desiredServiceState == .running {
MXLog.info("Enabling all send queues")
Task {
await client.enableAllSendQueues(enable: true)
@@ -1097,6 +1099,10 @@ class ClientProxy: ClientProxyProtocol {
// If we are using OAuth we want to cache the account management URL in volatile memory on the SDK side.
// To avoid the cache being invalidated while the app is backgrounded, we cache at every sync start.
await cacheAccountURL()
// Nudge the send queue listener to re-evaluate now that we're running; a resume doesn't otherwise
// emit, and the SDK only re-enables queues when client.resume() runs (gated behind the flag).
sendQueueStatusSubject.send(sendQueueStatusSubject.value)
case .suspended:
MXLog.info("Stopping sync")
await syncService.stop()