perf(xmpp): fix slow MAM/MUC-MAM and move OMEMO decryption off the main
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:
+15
-9
@@ -39,7 +39,9 @@ fallback на plaintext. UI сразу показывает optimistic message
|
||||
|
||||
Входящая stanza может прийти напрямую, через carbons или MAM. Сервис определяет
|
||||
peer, расшифровывает payload, использует `origin-id`/stanza id для дедупликации и
|
||||
передаёт value-type envelope в `AppModel`.
|
||||
передаёт value-type envelope в `AppModel`. Дедупликация выполняется по
|
||||
хеш-индексам (`origin-id`, `stanza-id`, `id`), поэтому стоимость применения пачки
|
||||
не растёт квадратично с размером архива.
|
||||
|
||||
Свежая установка начинает MAM с ограниченной последней страницы RSM, а не с
|
||||
самого старого сообщения. Инкрементальные проходы используют сохранённый
|
||||
@@ -48,14 +50,18 @@ peer, расшифровывает payload, использует `origin-id`/sta
|
||||
Каждая stanza проходит проверку `queryid` и источника личного архива. Martin
|
||||
публикует MAM-результаты на parser queue: ограниченный inbox принимает там всю
|
||||
страницу и делает единственный hand-off на main actor после финального IQ.
|
||||
Дешифрование выполняется по одной stanza с уступкой event loop, а декодированные
|
||||
изменения становятся видимыми только одной атомарной пачкой вместе с новой
|
||||
контрольной точкой. Один foreground-проход имеет конечный бюджет страниц и
|
||||
времени; ошибка страницы не перезапускает весь архив сама. При уходе приложения
|
||||
с экрана и на время записи/отправки видеосообщения активный MAM-запрос
|
||||
закрывается, чтобы дешифрование истории не конкурировало с камерой и upload.
|
||||
Только после commit `AppModel` обновляет SwiftUI, локальный snapshot и Apple
|
||||
Watch; незавершённый проход при timeout/disconnect отбрасывается целиком.
|
||||
Расшифровка OMEMO выполняется на отдельной серийной фоновой очереди, поэтому
|
||||
Signal-криптография не блокирует главный поток; построение envelope и публикация
|
||||
остаются на main actor. Видимый индикатор «Синхронизация истории…» показывается
|
||||
только на первичной странице, а инкрементальная догрузка backlog продолжается в
|
||||
фоне молча, публикуя декодированные изменения атомарными пачками по мере
|
||||
готовности страниц. MUC-архив проходит тем же путём и флашит декодированные
|
||||
групповые сообщения по завершении catch-up комнаты. Ошибка отдельной страницы
|
||||
автоматически повторяется ограниченное число раз. При уходе приложения с экрана
|
||||
и на время записи/отправки видеосообщения активный MAM-запрос закрывается, чтобы
|
||||
дешифрование истории не конкурировало с камерой и upload. Только после commit
|
||||
`AppModel` обновляет SwiftUI, локальный snapshot и Apple Watch; незавершённый
|
||||
проход при timeout/disconnect отбрасывается целиком.
|
||||
|
||||
Редактирование реализовано стандартным XEP-0308: исправление получает новый id и
|
||||
`<replace>` с id исходного сообщения. `AppModel` проверяет совпадение bare JID
|
||||
|
||||
Reference in New Issue
Block a user