Files
rust-xmpp/docs/MUC-RECOVERY.md
wt bff609097b
Test, build and publish / All tests and Linux binary (push) Failing after 30s
Test, build and publish / Container smoke test and Gitea publish (push) Skipped
- Уменьшено число последовательных синхронизаций до доставки: ordinary
MAM
  append использует один sync вместо четырёх, SM checkpoint — один
  вместо двух.
  Checksummed redo journals сохраняют commit-before-ACK и
  восстанавливают
  native archive/SM JSON exports после аварии.
- Ограничены рост журналов, ротация и tombstone GC. Старый `.rappend` и
  legacy
  JSON импортируются. Retain/save/purge не возвращают удалённые записи.
- Recovery синхронизирует валидный journal перед публикацией состояния;
  проверка
  checksum не заменяет durability barrier. EIO при adoption блокирует
  startup
  или offline handoff. Новые fault fixtures проверяют сохранность
  журнала и retry.
- Replay SM проверяет checksum/JSON всех frames, но создаёт и валидирует
  полный
  Record только для последнего snapshot, сокращая работу с superseded
  queues.
- `message-processing-slow` содержит времена MAM отправителя/получателя,
  доставки, carbons, offline/push и handled, а также число
  ресурсов/копий.
  Payload и секреты не добавляются в логи.
- Добавлена offline команда `storage-checkpoint CONFIG`: durable экспорт
  и
  передача archive writer/подготовка отката на legacy Rust. Не
  запускайте другого
  writer и не удаляйте journals до успешного завершения команды.
- Новые crash, partial-write, corruption, EIO, recovery, handoff и
  latency
  регрессии включены в GitHub Actions через verify-local.sh; отчёты
  сохраняются.

Измерения, ограничения и эксплуатация:
[docs/DURABLE-MESSAGE-IO.md](docs/DURABLE-MESSAGE-IO.md),
[docs/VALIDATION-0.8.3.md](docs/VALIDATION-0.8.3.md).
2026-10-21 13:14:19 +07:00

146 lines
14 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# MUC: протокол и восстановление 0.8.0
Реализация сопоставлена с предоставленной Prosody `cafd74b9c5ea`, прежде всего
`plugins/muc` и `mod_muc_mam.lua`. Известные встроенные возможности перенесены
в Rust; произвольный Lua-код и community-модули Prosody не исполняются.
Неизвестный явно включённый MUC-модуль отклоняется при запуске, а не молча
игнорируется. Список `modules_disabled` применяется с учётом общих и host-настроек,
в том числе для `muc_vcard` и `muc_occupant_id`.
## Что сохраняется
MUC теперь записывает единый журнал компонента `rust_muc_checkpoint`:
конфигурацию комнат, affiliations, текущие nick и роли участников, безопасные
поля presence и ограниченную историю обсуждения. Это относится к persistent
и временным комнатам и работает без MAM. Журнал содержит согласованное поколение
состояния; запись через временный файл, синхронизацию и rename предшествует
возврату результата операции и публикации соответствующих MUC-ответов.
При ошибке сохранения изменение состояния комнаты откатывается в памяти.
Сохранение выполняется при изменениях членства, конфигурации, affiliations,
ролей и истории, а также при штатной остановке. Поэтому восстановление больше
не зависит только от SIGTERM: после SIGKILL используется последнее успешно
зафиксированное поколение. Heartbeat обновляет отметки живых участников даже
в тихой комнате. Неудачный heartbeat фиксируется в журнале сервера; состояние,
которое не удалось сохранить, нельзя считать защищённым от следующего сбоя.
Обычная история без MAM сохраняет порядок, время сообщений и ограничения
`maxstanzas`, `maxchars`, `seconds`, `since`; subject хранится отдельно в
конфигурации комнаты. MAM остаётся самостоятельным архивом и не превращается
в часть одной транзакции со всеми внешними эффектами. Presence-события MAM
и groupchat-запросы остаются раздельными.
## Возвращение участников
Без сохранённой SM-сессии после запуска членство становится ожидающей записью, а не активным
адресатом маршрутизации. Автоматический MUC-вход возможен после новой
аутентификации, bind того же полного JID и общей available presence. Bare JID
или чужой resource не заменяют эту проверку. Обычный явный вход с MUC `<x/>`
тоже доступен; актуальные ограничения комнаты проверяются повторно.
Срок ожидания задаёт `muc_recovery_grace_period` в секундах: по умолчанию `300`,
диапазон `1..604800` (значения ограничиваются этими пределами). Живое членство
получает свежую отметку при фиксации и heartbeat. Уже ожидающая запись имеет
фиксированный срок: запросы, неудачные попытки и повторные перезапуски его
не продлевают. Неактивированные временные комнаты удаляются после истечения
срока.
Смена пароля, affiliations или иной конфигурации отменяет старые ожидающие
разрешения. Подтверждённые изменения роли, явный выход и удаление комнаты
попадают в журнал до ответа, поэтому следующая авария не должна возвращать
предыдущую роль или прежний nick. Успешное восстановление создаёт текущее
членство: при следующей аварии восстанавливается его последняя сохранённая
версия, а не навсегда погашенная старая запись.
В checkpoint presence входят только `show`, `status`, `priority`.
MUC-пароли и произвольные расширения presence туда не копируются. При живом
обмене обычные caps, avatar и idle сохраняются; присланные клиентом MUC identity,
occupant-id и hats фильтруются. Пароль комнаты остаётся в её конфигурации.
Если имеется действующая приватная SM-запись Rust, логическая сессия продолжает
членство без транспорта. При запуске повторно проверяются наличие и состояние
аккаунта и текущие ограничения комнаты. Маршрутизация восстанавливается до
приёма клиентов: сообщения для ещё не подключившегося участника попадают в его
сохранённую SM-очередь. Синтетические join presence и история повторно не
отправляются. Доставка по сети требует новой TLS/SASL-аутентификации и корректного
SM-токена того же владельца; native MUC-файлы сами по себе этого не разрешают.
## Native-файлы и переход между серверами
Native config, persistent index и `state/<roomnode>.dat` читаются и экспортируются
для совместимости с Prosody. При работе Rust источником согласованного
восстановления служит его журнал, а native-файлы являются экспортом после commit.
Устаревший экспорт после сбоя не должен возвращать предыдущее членство.
Native state без подтверждающих Rust-метаданных сам по себе не разрешает
автоматический вход.
Редактирование native-конфигурации администратором обнаруживается по отпечатку:
старые разрешения восстановления и история, привязанная к прежней политике,
отбрасываются; удаление ранее экспортированной конфигурации отменяет её
восстановление. Это не универсальное слияние параллельных записей двух серверов.
Для отката на Prosody остановите Rust и сохраните резервную копию всего
`data_path`. Начиная с0.8.3 перед сменой writer выполните новым binary
`rust-xmpp storage-checkpoint CONFIG`: он фиксирует MAM redo и SM JSON exports.
Это не перенос Rust SM-сессий в Prosody и не универсальная конверсия MUC journal.
Подробности — [DURABLE-MESSAGE-IO.md](DURABLE-MESSAGE-IO.md). Prosody использует native-экспорт и не читает Rust-журнал. Перед
возвратом с Prosody на Rust согласуйте данные и устраните устаревший
`rust_muc_checkpoint` в остановленном экземпляре: иначе неизменившиеся native
файлы могут быть приняты за экспорт предыдущего поколения Rust. Удаление
журнала означает отказ от его crash recovery, включая историю временных комнат.
Не запускайте оба сервера с общей записываемой директорией.
## Поддерживаемые политики
- Доступны hats из affiliation data, язык комнаты, роли presence broadcast,
политики PM и модераторских PM, формы конфигурации и offline affiliation presence.
- `muc_vcard` и `muc_occupant_id` управляют соответствующими возможностями.
MAM учитывает `muc_log_all_rooms`, `muc_log_presences`, `muc_log_include_total`.
- `restrict_room_creation`: `false` разрешает создание по умолчанию, `true`
ограничивает его настроенными администраторами, `"local"` — локальными
зарегистрированными пользователями и администраторами. `muc_max_rooms`
ограничивает число комнат; существующее членство не требует повторного
разрешения на создание.
- Регистрация учитывает `allow_unaffiliated_register`,
`enforce_registered_nickname`, `muc_registration_include_form`.
Срок tombstone задаёт `muc_tombstone_expiry` (по умолчанию 31 день).
- Администраторам компонента доступны ad-hoc команды
`http://prosody.im/protocol/muc#destroy` и
`http://prosody.im/protocol/muc#set-affiliation`. Полномочия проверяются
на каждом шаге; изменения проходят обычный механизм фиксации MUC.
Presence probe не создаёт участника и возвращает сведения только допущенному
участнику. Новый вход без MUC `<x/>` отклоняется; неизвестные типы presence
не превращаются во вход. Presence errors исключают соответствующую сессию;
message errors делают это для native-набора ошибок доставки. Последняя сессия
получает статус `333`; остальные ошибки приватного сообщения могут быть
переданы адресату. Сообщение с `subject` и `body` либо `thread` остаётся обычным
сообщением и не меняет тему комнаты.
## Границы и проверка
Старые TCP/TLS-сокеты после остановки процесса не существуют. Восстановление
членства MUC и XEP-0198 resume — отдельные механизмы. В 0.8.0 Hub сохраняет resumable
SM-сессии, счётчики и очередь неподтверждённых stanza. Resume проходит на новом
защищённом аутентифицированном транспорте, включая legacy SASL и SASL2;
успешный SM resume восстанавливает MUC без дополнительной available presence.
Входящая stanza учитывается в handled-счётчике после обработки. Heartbeat и
штатная остановка сохраняют снимок; offline deadline не продлевается простыми
проверками или повторными запусками.
SM-снимок приватный: предел 256 MiB суммарно, 8 MiB и 4096 stanza на сессию.
Он не является native-форматом Prosody. Нельзя обещать сохранение сокета или
ровно одну доставку при неопределённом результате сетевой отправки.
Буфер истории ограничен `max_history_messages` (по умолчанию 100, предел 4096),
состояние комнаты — 4096 ресурсами. Большие необязательные поля presence
исключаются из checkpoint; отдельные сообщения истории больше 16 KiB не
восстанавливаются. Общий checkpoint компонента ограничен 16 MiB: превышение
лимита приводит к ошибке записи, а не к успешному подтверждению несохранённого
изменения. Долговечность предполагает исправный диск и файловую систему,
соблюдающую синхронизацию записи.
Команды и результаты проверки версии 0.8.0 публикуются в
[VALIDATION-0.8.0.md](VALIDATION-0.8.0.md). Полный прогон завершён успешно. Общие границы совместимости:
[COMPATIBILITY.md](COMPATIBILITY.md).