REPOSITORY / ScuroNeko/Laniakea

Wiki

KNOWLEDGE REPOSITORY
5
Bot Lifecycle RU
ScuroNeko edited this page 2026-05-20 13:22:27 +03:00

Bot Lifecycle RU

English version: Bot-Lifecycle

Это краткая русскоязычная версия страницы про жизненный цикл Bot. Полная и наиболее актуальная страница: Bot-Lifecycle.

Жизненный цикл в одном списке

  1. Собрать BotOpts.
  2. Создать Bot через NewBot[T](opts).
  3. Полностью настроить бот: плагины, middleware, фоновые задачи, политику данных callback, l10n и app data.
  4. Запустить через Run(), RunWithContext(...) или RunWebhookWithContext(...).
  5. Остановить выполнение через завершение runtime или отмену context.
  6. Освободить локальные ресурсы через Close().
  7. Для следующего запуска создать новый Bot.

Главное правило: Bot используется только один раз.

Что делает NewBot(...)

Конструктор:

  • валидирует opts;
  • создает внутренние tgapi.API и Uploader;
  • поднимает логгеры;
  • готовит default DraftProvider;
  • вызывает getMe, чтобы проверить токен и получить username бота.

NewBot(...) сразу падает, если:

  • opts == nil;
  • токен пустой;
  • Telegram не принимает токен.

Что нужно закончить до runtime

До запуска обычно нужно завершить:

  • SetAppData(...)
  • AddPrefixes(...)
  • SetPayloadType(...)
  • SetStrictPayloadType(...)
  • SetUpdateTypes(...) и AddUpdateType(...)
  • AddPlugins(...)
  • AddMiddleware(...)
  • AddRunner(...)
  • SetL10n(...)
  • SetDraftProvider(...)
  • SetSessionStore(...)
  • SetSceneScopePriority(...)
  • SetErrorTemplate(...)

Это важно, потому что механизм выполнения не рассчитан на модель “запустили, а потом продолжаем собирать конфигурацию на лету”.

Почему AddPlugins(...) так важен

AddPlugins(...) копирует конфигурацию плагина внутрь бота.

Практически это значит:

  • сначала закончи настройку плагина;
  • потом регистрируй его;
  • не рассчитывай, что дальнейшая мутация исходного *Plugin будет официально поддерживаемой частью API.

Бот клонирует commands, payload handlers, update handlers, scenes, middleware, logger и OnClose callbacks из плагина. После регистрации исходный *Plugin уже не является авторитетным источником конфигурации для этого экземпляра Bot.

Фазы фиксации конфигурации

В Laniakea удобно думать о трёх фазах:

  1. Построение и настройка Bot после NewBot[T](opts).
  2. Снимок конфигурации плагина в AddPlugins(...).
  3. Фиксация bot-level конфигурации после первого Run(), RunWithContext(...) или RunWebhookWithContext(...).

Практически это значит:

  • структуру плагина нужно закончить до AddPlugins(...);
  • структуру Bot нужно закончить до первого запуска runtime;
  • поздние структурные изменения в Bot считаются намеренно игнорируемыми.

После старта runtime такие методы, как AddPlugins(...), AddMiddleware(...), AddRunner(...), AddPrefixes(...), SetPayloadType(...), SetStrictPayloadType(...), SetDraftProvider(...), SetSessionStore(...), SetSceneScopePriority(...), SetL10n(...), SetAppData(...), SetUpdateTypes(...), AddUpdateType(...) и SetErrorTemplate(...), игнорируются.

Что значит «игнорируется»

Это значит, что метод возвращается без изменения структурного runtime-состояния.

Laniakea предпочитает предсказуемый no-op вместо частичной live-мутации running bot. Это убирает:

  • неясный порядок между конфигурационными изменениями и обработкой update;
  • гонки вокруг общего состояния бота;
  • путаницу в том, влияет ли изменение только на будущие update или ещё и на уже принятую работу;
  • разные ментальные модели для snapshot-поведения плагинов и bot-level состояния.

Run(), RunWithContext(...) и RunWebhookWithContext(...)

Run() — это короткая форма для простых случаев.

RunWithContext(...) — основной polling-вариант. Он:

  • корректно завершает выполнение через ctx.Done();
  • ждет завершения queued updates;
  • корректно дожидается фоновых задач.

RunWebhookWithContext(...) — webhook-вариант runtime. Он использует тот же single-use контракт, тот же запуск runners, ту же очередь обновлений и ту же worker-pool обработку.

Если bot уже был запущен раньше, повторный запуск вернет ErrBotAlreadyRun.

Если ты переводишь уже существующий deployment с webhook-доставки на polling, сначала удали текущий webhook через CloseWebhook() или низкоуровневый tgapi.DeleteWebhook(...). Пока webhook не удалён, Telegram продолжает доставлять update через него.

Для webhook-специфичных опций, транспортного поведения и практических советов смотри Webhook-Runtime-RU.

Что происходит во время выполнения

Во время работы бот делает три вещи:

  • принимает updates через polling или webhook ingress;
  • складывает updates во внутреннюю очередь;
  • обрабатывает их через worker pool.

Полезно помнить:

  • размер worker pool управляется через MaxWorkers;
  • polling при ошибках использует экспоненциальный backoff;
  • после отмены context сначала прекращается приём новых updates, потом дренируется очередь, потом дожидаются фоновые задачи.

Close() и CloseRemote()

Это разные вещи.

Close():

  • закрывает плагины через Plugin.Close();
  • закрывает webhook logger, если его успел инициализировать webhook runtime;
  • закрывает uploader;
  • закрывает локальный API client;
  • закрывает логгер запросов и основной логгер.

CloseRemote(ctx):

  • отправляет Telegram Bot API метод close;
  • относится к удаленной сессии, а не к локальным ресурсам процесса.

Обычно боту нужен именно Close().

RunWithContext(...) и RunWebhookWithContext(...) не заменяют Close(): локальные ресурсы всё равно нужно закрывать отдельно.

Частые ошибки

  • Пытаться повторно использовать тот же Bot.
  • Продолжать менять bot-level конфигурацию после старта runtime.
  • Забывать Close() после завершения runtime.
  • Менять плагины после AddPlugins(...) и ждать, что бот это гарантированно увидит.
  • Регистрировать repeating runner без timeout.

Что читать дальше