Перейти к содержанию

Жизненный цикл

Данный документ описывает контракт жизненного цикла компонентов BotFlux. Все положения, описанные ниже, являются обязательными для соблюдения реализациями компонентов и инфраструктуры.


Модель управления

Жизненный цикл в BotFlux построен по направленной модели:

  • команды управления передаются сверху вниз (start(), stop())
  • события состояния передаются снизу вверх через подписку (addListener(Status, Throwable))

Команды жизненного цикла инициируются исключительно владельцем компонента. Компоненты не управляют жизненным циклом других компонентов и не вызывают start() или stop() у внешних объектов.

События жизненного цикла предназначены только для наблюдения, логирования и оркестрации.


Статусы жизненного цикла

Каждый компонент с жизненным циклом находится ровно в одном из следующих состояний:

  • NEW — компонент создан
  • STARTING — компонент выполняет инициализацию
  • ACTIVE — компонент запущен и готов к работе
  • STOPPING — компонент выполняет корректную остановку
  • TERMINATED — компонент полностью остановлен
  • FAILED — выполнение завершилось с ошибкой; состояние сопровождается Throwable

Состояния FAILED и TERMINATED являются терминальными.


Одноразовость компонентов

Все компоненты BotFlux с жизненным циклом являются одноразовыми:

  • метод start() допускается к вызову только один раз
  • метод stop() допускается к вызову только один раз
  • повторный переход в STARTING невозможен

После перехода в TERMINATED или FAILED повторный запуск компонента запрещён контрактом. Для нового запуска требуется создание нового экземпляра компонента.


Допустимые переходы состояний

stateDiagram-v2
    New --> Starting
    New --> Active
    New --> Stopping
    New --> Terminated
    New --> Failed
    Starting --> Active
    Starting --> Stopping
    Starting --> Terminated
    Starting --> Failed
    Active --> Stopping
    Active --> Terminated
    Active --> Failed
    Stopping --> Terminated
    Stopping --> Failed
    Stopping --> Terminated
    Stopping --> Failed

Диаграмма определяет полный набор допустимых переходов состояний. Переходы вне данного графа отклоняются реализацией жизненного цикла и недоступны компонентам.


События жизненного цикла

Компонент обязан поддерживать регистрацию слушателей:

addListener(BiConsumer<Status, Throwable>)

Слушатель вызывается после фиксации перехода состояния.

Правила:

  • при переходе в FAILED передаётся соответствующий Throwable
  • при штатных переходах Throwable равен null
  • слушатели не должны выбрасывать исключения
  • слушатели не должны блокировать поток выполнения

Слушатели не предназначены для управления жизненным циклом компонентов.


Жизненный цикл BotFlux

Порядок запуска

Вызов:

botFlux.start();

инициирует запуск системы в следующем порядке:

  1. Запуск BotFluxContext
  2. Запуск компонентов, зарегистрированных в контексте
  3. Запуск DispatcherManager
  4. Запуск диспетчеров

Каждый шаг выполняется только после успешного завершения предыдущего.


BotFluxContext

BotFluxContext является владельцем всех зарегистрированных компонентов.

При запуске контекста:

  1. Контекст переходит в STARTING
  2. Все компоненты запускаются в определённом порядке
  3. При ошибке любого компонента контекст переходит в FAILED
  4. При успешном запуске всех компонентов контекст переходит в ACTIVE

DispatcherManager

DispatcherManager запускается только после перехода контекста в ACTIVE.

При запуске:

  1. Менеджер переходит в STARTING
  2. Создаются и запускаются диспетчеры
  3. После успешного запуска всех диспетчеров менеджер переходит в ACTIVE

Диспетчеры

Каждый диспетчер:

  • является компонентом с жизненным циклом
  • подчиняется общим правилам переходов состояний
  • запускается и останавливается менеджером диспетчеров

Остановка системы

Остановка BotFlux выполняется в обратном порядке запуска:

  1. Остановка диспетчеров
  2. Остановка DispatcherManager
  3. Остановка BotFluxContext
  4. Остановка всех компонентов контекста

Метод stop() является идемпотентным и гарантирует переход компонента в TERMINATED.


Диаграмма передачи жизненного цикла

flowchart TD
    S@{shape: circle, label: "Control"}
    BF[BotFlux]
    BF[BotFlux]
    BFC[BotFluxContext]
    BC@{shape: procs, label: "BotComponent"}
    BDM[BotDispatcherManager]
    BD@{shape: procs, label: "BotDispatcher"}
    BG[BotGateway]

    S --> |Command| BF
    BF --> |Event| S

    BF --> |Command| BFC
    BFC --> |Event| BF

    BF --> |Command| BDM
    BDM --> |Event| BF

    BFC --> |Command| BC
    BC --> |Event| BFC

    BDM --> |Command| BD
    BD --> |Event| BDM

    BD --> |Command| BG
    BG --> |Event| BD