perf(xmpp): fix slow MAM/MUC-MAM and move OMEMO decryption off the main
iOS CI / Build and Test SwiftUI App (push) Canceled after 0s
Build Unsigned iOS and macOS Apps / Build Unsigned iOS IPA (push) Canceled after 0s
Build Unsigned iOS and macOS Apps / Build macOS ZIP (push) Canceled after 0s

thread

- Replace O(n^2) origin-id/stanza-id lookups in AppModel with hash
  indexes
  and stop rebuilding the whole index on every unseen stanza-id, so
  archive
  application no longer grows quadratically with history size.
- Run OMEMO decryption on a serial background queue instead of the main
  actor, and decrypt archived stanzas in small batches with a shorter
  yield,
  keeping the UI responsive during large archive catch-ups.
- Show the "Синхронизация истории…" banner only for the one-page
  bootstrap
  window; incremental backlog catch-up continues silently in the
  background.
- Fix MUC-MAM: publish decoded group mutations at the end of room
  catch-up;
  they were previously accumulated and then silently dropped.
- Retry a failed catch-up pass automatically (bounded) and lengthen the
  query/apply timeouts so a single slow page no longer leaves history
  unloaded until the next app activation.
This commit is contained in:
wt committed 2026-08-17 15:32:05 +07:00
1 parent dee7e94e92
commit 9b56d2ebcf
8 files changed
+329 -167

No files matched your search

@@ -6,10 +6,14 @@ import Foundation
enum ArchiveMessageBatchPolicy {
static let pageSize = 24
static let bootstrapMessageLimit = 40
static let decodeSliceSize = 1
/// Decrypt this many archived stanzas per main-actor slice before yielding.
/// One-by-one decryption turns a large MAM catch-up into hours of serialized
/// work; a small batch keeps frames mostly intact while cutting the number
/// of run-loop hand-offs by the same factor.
static let decodeSliceSize = 8
static let maximumBufferedStanzas = 48
/// Leave roughly half of a 60 Hz frame between archived decryptions. This
/// keeps UIScrollView touch handling responsive even when OMEMO work is
/// unusually expensive on older devices.
static let interSliceDelayNanoseconds: UInt64 = 8_000_000
/// A short yield between archived decryption slices keeps touch handling
/// responsive without the 8 ms per single message that previously dominated
/// catch-up time.
static let interSliceDelayNanoseconds: UInt64 = 1_000_000
}