Files
rust-xmpp/docs/MUC-RECOVERY.md
T
wt 7f60661eef - MUC сохраняет согласованный журнал конфигурации, affiliations, nick,
ролей,
  членства и ограниченной истории без MAM. Изменение фиксируется до
  публикации
  ответа; при ошибке записи состояние комнаты откатывается.
- Crash recovery использует последнее сохранённое поколение после
  SIGKILL,
  включая временные комнаты. Heartbeat обновляет живое членство;
  ожидающие записи сохраняют исходный deadline через повторные
  перезапуски.
  `muc_recovery_grace_period`: по умолчанию 300 секунд, пределы
  1..604800.
- Подтверждённые выходы, смена nick, ролей и политик комнаты не
  заменяются
  старой записью восстановления. Native config/state остаются экспортом
  для
  Prosody; согласованное восстановление Rust использует собственный
  sidecar.
- Исправлены MUC probe, неизвестные типы presence, вход без MUC `<x/>`,
  ошибки
  доставки и статус 333. Обычные presence extensions сохраняются в живом
  обмене; поддельная MUC identity фильтруется. `subject` вместе с `body`
  либо
  `thread` не изменяет тему комнаты.
- Подключены `muc_max_rooms`, `restrict_room_creation`, политики
  регистрации
  и зарегистрированного nick, `muc_tombstone_expiry`; добавлены
  встроенные
  административные ad-hoc команды уничтожения комнат и изменения
  affiliation.
- Hub сохраняет resumable XEP-0198 сессии, счётчики и очередь. Resume
  после
  перезапуска доступен на новом TLS/SASL-транспорте через legacy SASL и
  SASL2.
  Действующие приватные SM-записи восстанавливают логические сессии и
  MUC
  до открытия listeners: offline-доставка попадает в очередь,
  синтетический
  join и история повторно не отправляются. SM resume не требует
  дополнительной
  available presence; без SM восстановление MUC требует новой
  аутентификации
  точного полного JID и available presence либо явного MUC-входа.
  Входящий handled-счётчик обновляется после обработки. Сокеты TCP/TLS
  не сохраняются; неопределённая сетевая отправка допускает повторную
  доставку.
- Известные встроенные MUC-возможности Prosody отображаются на
  Rust-реализацию.
  Произвольные Lua/community-модули не исполняются; неизвестные явно
  включённые
  MUC-модули отклоняются при запуске. Общие и host `modules_disabled`
  учитываются
  для vCard и occupant-id.

Порядок восстановления, ограничения хранения и отката на Prosody:
[docs/MUC-RECOVERY.md](docs/MUC-RECOVERY.md).

Проверка: 293 Rust tests, Clippy/fmt/release, полный сетевой прогон, 500
TLS
MUC+SM ресурсов с SIGKILL/resume и native reference — успешно.
Подробности: [docs/VALIDATION-0.8.0.md](docs/VALIDATION-0.8.0.md).
2026-10-20 17:34:43 +07:00

143 lines
13 KiB
Markdown
Raw 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`. 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).