feat: perform background fetch from all transports - #8592
Conversation
50704f9 to
7720b34
Compare
So every background fetch call will always go the full timeout if one of your relays on one of your profiles is offline? In that case android also needs to be updated as I think they also synchronously wait on this function (albeit only for 10 seconds) |
Offline relays will typically immediately fail, so there is no waiting for that. But if you implement concurrent event processing during background fetch, you shouldn't have to worry. The first working relay delivering a message will give you an incoming message, no matter what other connections hang or still need time. |
With I/O stopped, `background_fetch()` connected only to the transport of `configured_addr` and we now instead fan out to all transports in a controlled loop. Also drop the quota check from this background fetch path: its result is in-memory only, discarded when the iOS notification service exits, and the regular scheduler fetching refreshes it every 60s anyway. Moreover, quota errors/running full is pretty rare since relays generally automatically stay under quota these days. It's another round trip for each transport of each profile and simply not neccessary. Also adds previosly missing online tests and adds `transport_id` to `ImapInboxIdle` Event
7720b34 to
6c31d9e
Compare
With I/O stopped,
background_fetch()connected only to the transport ofconfigured_addr(see #8572) and we now instead fan out to all transports once in a controlled loop without any notion of primary. This createsNIMAP connections withN=num(all_transports_of_all_profiles), instead ofN=num(all_profiles). Whichever connection for each profile wins, will fetch and lock out the other connections, so that RAM usages through fetching actual IMAP messages should not change.Known usages
background_fetchin UIs:Android permanent background fetch (timeout 300s): https://github.com/deltachat/deltachat-android/blob/49aa4ab189e7ab61441aaef14a9ad9249e44c050/src/main/java/org/thoughtcrime/securesms/service/FetchForegroundService.java#L73-L82
Android FCM background fetch (timeout 10s): https://github.com/deltachat/deltachat-android/blob/49aa4ab189e7ab61441aaef14a9ad9249e44c050/src/main/java/org/thoughtcrime/securesms/service/FetchForegroundService.java#L88-L106
iOS NSE background fetch (timeout 15s):
https://github.com/deltachat/deltachat-ios/blob/64804f6c467faedabfd7b77b1f9538c3f6b7d201/DcNotificationService/NotificationService.swift#L5-L8)
Deltatouch (UbuntuTouch) background fetch (timeout 4s) https://codeberg.org/lk108/deltatouch/src/commit/ac45eb90ede50818df00583b9111fbe26991e460/package/click/pushhelper.cpp#L223
With this PR, the overall behaviour should already improve, as we now use the first transport that connects fastest during
background_fetch, instead of relying on a "primary" one only. However, current callers would still wait for all transports of all profiles to finish their single background fetch-round with the respective timeouts.This can not be fixed in core, but UIs could drain events concurrently during background fetch, and cancel any fallback-handling if a real notification arrives. This should kind of guarantee UIs see the first message from whichever transport and whichever profile it arrives, and do not have to wait to the end of all background fetches (which might timeout, be killed by the OS etc.).
The PR also drops the
Nquota checks from background fetch: the check result is in-memory only, discarded when the iOS NSE exits, and the regular scheduler fetching refreshes quota every 60s anyway. Moreover, quota full are pretty rare since relays generally automatically stay under quota these days. This savesNconcurrent round trips during background fetch and is simply not necessary.Also adds previously missing online tests.