Files
config_manager/README.md

8.1 KiB
Raw Blame History

Config Manager

Описание

Пакет предназначен для запуска приложений. Класс ConfigManager реализует точку входа программы и предоставляет актуальную конфигурацию приложения, а также упрощает настройку логирования.

ConfigManager v2: устройство и взаимосвязи

ConfigManager v2 — точка входа приложения. Он наследует внутреннюю логику от _RuntimeController (циклы воркера и обновления конфига, запуск/остановка каналов управления).

Ядро (core):

  • ConfigLoader — читает конфиг из файла (YAML/JSON), считает хеш и отдаёт конфиг только при изменении; при ошибке парсинга возвращает последний валидный конфиг.
  • WorkerLoop — в отдельном потоке циклически вызывает ваш метод execute() с паузой между вызовами; реагирует на событие остановки и колбэки успеха/ошибки.
  • LogManager (v1) — применяет секцию log из конфига к логированию (dictConfig).
  • HealthAggregator — собирает состояние: жизненный цикл (idle/starting/running/…), время последнего успешного execute() и таймаут здоровья; формирует единый ответ для health (ok/unhealthy).
  • ControlChannelBridge — один мост для всех каналов: обработчики on_start/on_stop/on_status (сброс/установка halt, текст статуса).

Каналы управления (control):

  • ControlChannel — абстрактный контракт: start(on_start, on_stop, on_status), stop().
  • HttpControlChannel — HTTP API (/health, /actions/start, /actions/stop, /actions/status); использует UvicornServerRunner; для /health вызывает HealthAggregator.collect(), для действий — переданные обработчики из ControlChannelBridge.
  • TelegramControlChannel — реализация через long polling Telegram; команды /start, /stop, /status вызывают переданные обработчики.

Поток работы: при start() менеджер собирает список каналов (при management_settings.enabledHttpControlChannel, плюс опционально control_channel / control_channels), поднимает все каналы с одним ControlChannelBridge, затем запускает два цикла: WorkerLoop и периодическое обновление конфига через ConfigLoader. Остановка по halt (через любой канал) завершает оба цикла; в конце останавливаются все каналы.

Диаграмма классов (v1 и v2)

classDiagram
    direction TB

    class ConfigManager {
        +str path
        +Any config
        +float update_interval
        +float work_interval
        -Event _halt
        -Task _task
        +start() async
        +stop() async
        +execute()*
        -_worker_loop() async
        -_periodic_update_loop() async
        -_update_config() async
    }

    class ConfigManagerV2 {
        +str path
        +Any config
        +float update_interval
        +float work_interval
        -ConfigLoader _loader
        -LifecycleState _state
        +start() async
        +stop() async
        +execute()*
        +get_health_status() HealthPayload
        -_run() async
        -_worker_loop() async
        -_periodic_update_loop() async
    }

    class _RuntimeController {
        <<внутренний>>
        -_on_execute_success()
        -_on_execute_error(exc)
        -_worker_loop() async
        -_periodic_update_loop() async
        -_start_control_channels() async
        -_stop_control_channels() async
        -_run() async
    }

    class ConfigLoader {
        +str path
        +Any config
        +Any last_valid_config
        +load_if_changed() async
        +parse_config(data) Any
        -_read_file_sync() str
        -read_file_async() async
    }

    class WorkerLoop {
        -Callable execute
        -Callable get_interval
        -Event halt_event
        +run() async
    }

    class LogManager {
        +apply_config(config) None
    }

    class ControlChannel {
        <<абстрактный>>
        +start(on_start, on_stop, on_status) async*
        +stop() async*
    }

    class TelegramControlChannel {
        -str _token
        -int _chat_id
        +start(on_start, on_stop, on_status) async
        +stop() async
        -_poll_loop() async
    }

    class HttpControlChannel {
        -UvicornServerRunner _runner
        -Callable _health_provider
        +start(on_start, on_stop, on_status) async
        +stop() async
        +int port
    }

    class HealthAggregator {
        -Callable get_state
        -Callable get_app_health
        +collect() async HealthPayload
    }

    class ControlChannelBridge {
        -Event _halt
        -Callable _get_state
        -Callable _get_status
        +on_start() async str
        +on_stop() async str
        +on_status() async str
    }

    class UvicornServerRunner {
        -Server _server
        -Task _serve_task
        +start(app) async
        +stop() async
        +int port
    }

    ConfigManager --> LogManager : использует
    ConfigManagerV2 --|> _RuntimeController : наследует
    ConfigManagerV2 --> ConfigLoader : использует
    ConfigManagerV2 --> LogManager : использует
    ConfigManagerV2 --> HealthAggregator : использует
    ConfigManagerV2 --> ControlChannelBridge : использует
    ConfigManagerV2 ..> ControlChannel : список каналов
    _RuntimeController ..> WorkerLoop : создаёт в _worker_loop
    TelegramControlChannel --|> ControlChannel : реализует
    HttpControlChannel --|> ControlChannel : реализует
    HttpControlChannel --> UvicornServerRunner : использует
    HttpControlChannel ..> HealthAggregator : health_provider
    ControlChannelBridge ..> ControlChannel : on_start, on_stop, on_status

Логирование (v2)

Логирование настраивается из конфигурационного файла только если в нём есть секция log в формате dictConfig. Если секции log нет, менеджер пишет предупреждение в лог, а уровень Python по умолчанию (WARNING) сохраняется — сообщения INFO/DEBUG могут не отображаться.

Как проверить, что конфигурация логирования применилась:

  • Убедитесь, что путь к файлу конфига верный и файл загружается при старте (в логах нет ошибки чтения конфига).
  • Убедитесь, что в конфиге есть ключ log с version: 1, handlers и loggers (пример — tests/config.yaml).
  • После старта в логе должно появиться сообщение уровня INFO: "Logging configuration applied" (из config_manager.v1.log_manager). Если его нет, либо секция log отсутствует (будет предупреждение), либо уровень root/пакета выше INFO.

Установка

pip install git+https://git.lesha.spb.ru/alex/config_manager.git

Контакты