Config Manager
Описание
Пакет предназначен для запуска приложений. Класс ConfigManager реализует точку входа программы и предоставляет актуальную конфигурацию приложения, а также упрощает настройку логирования.
ConfigManager v2: устройство и взаимосвязи
ConfigManager v2 — точка входа приложения. Он наследует внутреннюю логику от _RuntimeController (циклы воркера и обновления конфига, запуск/остановка каналов управления).
Ядро (core):
- ConfigLoader — читает конфиг из файла (YAML/JSON), считает хеш и отдаёт конфиг только при изменении; при ошибке парсинга возвращает последний валидный конфиг.
- WorkerLoop — в отдельном потоке циклически вызывает ваш метод
execute()с паузой между вызовами; реагирует на событие остановки и колбэки успеха/ошибки. - LogManager — применяет секцию
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.enabled: true в config.yaml (секция management) добавляется HttpControlChannel, плюс опционально control_channel / control_channels в конструкторе. Все каналы поднимаются с одним ControlChannelBridge, затем запускаются два цикла: WorkerLoop и периодическое обновление конфига через ConfigLoader. Остановка по halt (через любой канал) завершает оба цикла; в конце останавливаются все каналы. Настройки HTTP-канала (host, port, timeout, health_timeout) задаются в config.yaml в секции management.
Диаграмма классов (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.v2.core.log_manager). Если его нет, либо секцияlogотсутствует (будет предупреждение), либо уровень root/пакета выше INFO.
Установка
pip install git+https://git.lesha.spb.ru/alex/config_manager.git
Контакты
- e-mail: lesha.spb@gmail.com
- telegram: https://t.me/lesha_spb