简体中文 English 繁體中文 日本語 Русский
本文为静态镜像,内容以交互版为准 在交互式文档中心打开 →

Теневые модули и постепенный переход на новый вариант

Теневой модуль = новая версия того же модуля, которая параллельно с уже запущенной старой версией работает в тестовом режиме под собственным владельцем (например, roll_shadow). Он получает копии реальных событий, а его исходящие вызовы перехватываются и фиксируются, вместо того чтобы быть реально отправленными.
Сравнивая поведение двух версий в shadow_diff, можно убедиться, что новая версия безопасна, после чего с помощью promote можно одним действием перевести её в статус основной, а с помощью dismiss — в любой момент отказаться от теневого режима. Код модуля не изменяется, вся работа происходит с помощью API в режиме выполнения: подобно операциям load / unload / reload, такие действия можно вызывать через Dashboard или пользовательские модули управления, без необходимости писать какие-либо конфигурационные параметры.

{!--< tips >!--}

  1. Запуск: await sdk.module.shadow_start("roll", source="путь/к/v2") — новая версия кода работает параллельно со старой под собственным владельцем (по умолчанию имя владельца берётся из пути)
  2. Теневой модуль не участвует в реальном распределении и не влияет на граф зависимостей: команды с таким же именем выполняются в теневом каталоге, маршрутизация регистрируется, но не подключается, события жизненного цикла тихо игнорируются, а module.call и разрешение зависимостей по-прежнему указывают на v1
  3. Переход на новую версию всегда подтверждается человеком: await sdk.module.promote_shadow("roll"), в случае неудачи автоматически происходит откат к старому экземпляру, который продолжает обслуживать запросы; dismiss_shadow позволяет в любой момент отказаться от теневого режима {!--< /tips >!--}

Быстрый старт

# Код v2: обычный модуль, без теневого режима (любой каталог, например downloads/roll_v2/)
# В онлайн-боте (через Dashboard / модуль управления), запуск грейд-теста одной строкой:
await sdk.module.shadow_start("roll", source="downloads/roll_v2")
# → Теневой модуль с отдельным owner "roll_v2" параллельно работает с v1, исходящие сообщения перехватываются и записываются

# Сравнение поведения во время тестирования:
report = sdk.module.shadow_diff("roll")
# {"shadow_owner": "roll_v2", "count": 3, "aligned": [...]}

После проверки без ошибок:

await sdk.module.promote_shadow("roll")   # Промоутить, при ошибке автоматически откатить к v1
await sdk.module.dismiss_shadow("roll")   # Или отменить теневой режим

Пять изолирующих барьеров

Барьер Механизм
Копия события Теневой обработчик получает независимую копию события (с меткой shadow) — изменения / признание / остановка распространения теневого события влияют только на копию, не затрагивая оригинальную цепочку событий
Выходная дверь Все вызовы DSL Send и Api теневого события перехватываются и регистрируются (возвращается фиктивный ответ), событие не отправляется наружу — теневой обработчик не будет повторно отвечать
Слой перекрытия хранилища Запись KV теневого события происходит в слое перекрытия в памяти и не сохраняется в базу данных; чтение сначала проверяет слой перекрытия, при неудаче — обращается к реальной базе данных (灰度 процесс работает с реальными данными); удаление помечается как "могильный камень"
Блокировка маршрутизации HTTP/WS/SSE маршруты теневого события регистрируются, но не подключаются; команды с тем же именем записываются в каталог теневых команд, методы платформенных событий запрещены к вставке
Тихий жизненный цикл Теневой обработчик не транслирует собственные события жизненного цикла и не участвует в экосистемной зависимости (вызовы module.call и разрешение зависимостей по-прежнему указывают на v1, чтобы избежать зависимости от незавершённого продукта)

Наследование конфигурации: теневой обработчик по умолчанию наследует конфигурационные разделы оригинального модуля (иначе серая версия будет отличаться от оригинала), после перевода в основной режим конфигурация применяется на месте.

Честные границы (не остановить)

Промотирование и откат

Процесс promote: создание снимка текущей версии (включая все зависимые модули) → полное удаление → регистрация теневого экземпляра с настоящим именем → загрузка → при сбое на любом этапе автоматический откат, старый экземпляр продолжает обслуживать запросы (семантика "по возможности": эффекты, вызванные уже выполненным on_unload, не могут быть отменены, после отката старый экземпляр находится в состоянии завершения). После успешного промотирования теневые ресурсы утилизируются, и связь снимается; конфигурация оригинального модуля применяется на месте.

Примечание о сохранении изменений: промотирование происходит в режиме выполнения — после перезапуска будет продолжать работать версия v2. Необходимо сохранить новую версию (установить новую версию с помощью pip install -U или заменить файлы плагина). Переключение в режиме выполнения не заменяет пакетный менеджер.

Связанные документы