From c5a78d80d4d75ca119afb1c487e0de42c3e40618 Mon Sep 17 00:00:00 2001 From: zosimovaa Date: Wed, 4 Mar 2026 10:38:21 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9F=D1=80=D0=B0=D0=B2=D0=BA=D0=B8=20=D0=BE?= =?UTF-8?q?=D0=BF=D0=B8=D1=81=D0=B0=D0=BD=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 867 +++++++++--------- .../Architectural constraints.md | 0 .../Mail Order Bot Migration Plan.md | 0 requirements/README.md | 469 ++++++++++ .../architecture.md | 0 vision.md => requirements/vision.md | 0 6 files changed, 890 insertions(+), 446 deletions(-) rename Architectural constraints.md => requirements/Architectural constraints.md (100%) rename Mail Order Bot Migration Plan.md => requirements/Mail Order Bot Migration Plan.md (100%) create mode 100644 requirements/README.md rename architecture.md => requirements/architecture.md (100%) rename vision.md => requirements/vision.md (100%) diff --git a/README.md b/README.md index 5a6c2a7..4a6a614 100644 --- a/README.md +++ b/README.md @@ -1,469 +1,444 @@ # PLBA -`PLBA` is a reusable platform runtime for business applications. - -It solves platform concerns that should not live inside domain code: -- application lifecycle -- worker orchestration -- configuration loading from YAML -- tracing -- health aggregation -- runtime status reporting -- HTTP control endpoints -- logging configuration - -Business applications depend on `plba` as a package and implement only their own business behavior. - -## Architecture - -Current PLBA architecture is built around one core idea: -- the runtime manages a set of application workers - -A worker is any runtime-managed active component with a unified lifecycle: -- `start()` -- `stop(force=False)` -- `health()` -- `status()` - -This means PLBA does not require separate platform categories like `source` and `consumer`. -If an application needs polling, queue processing, listening, scheduled work, or another active loop, it is implemented as a worker. - -### Main runtime model - -1. application creates `RuntimeManager` -2. runtime loads configuration -3. runtime applies logging configuration -4. application module registers workers and supporting services -5. runtime starts all workers -6. workers execute business-related loops or processing -7. runtime aggregates health and status -8. runtime stops workers gracefully or forcefully - -## Core concepts - -### `ApplicationModule` - -File: [application.py](/Users/alex/Dev_projects_v2/apps/plba/src/app_runtime/contracts/application.py) - -Describes a business application to the runtime. - -Responsibilities: -- provide module name -- register workers -- register queues if needed -- register handlers if needed -- register health contributors -- compose application-specific objects - -`ApplicationModule` does not run the application itself. -It only declares how the application is assembled. - -### `Worker` - -File: [worker.py](/Users/alex/Dev_projects_v2/apps/plba/src/app_runtime/contracts/worker.py) - -The main runtime-managed contract. - -Responsibilities: -- start its own execution -- stop gracefully or forcefully -- report health -- report runtime status - -This is the main extension point for business applications. - -### `TaskQueue` - -File: [queue.py](/Users/alex/Dev_projects_v2/apps/plba/src/app_runtime/contracts/queue.py) - -Optional queue abstraction. - -Use it when application workers need buffered or decoupled processing. - -PLBA does not force every application to use a queue. -Queue is one supported pattern, not the foundation of the whole platform. - -### `TaskHandler` - -File: [tasks.py](/Users/alex/Dev_projects_v2/apps/plba/src/app_runtime/contracts/tasks.py) - -Optional unit of business processing for one task. - -Useful when a worker follows queue-driven logic: -- worker takes a task -- handler executes business logic - -### `TraceService` - -File: [service.py](/Users/alex/Dev_projects_v2/apps/plba/src/app_runtime/tracing/service.py) - -Platform trace service. - -Responsibilities: -- create trace contexts -- resume trace from task metadata -- write context records -- write trace messages - -Business code should use it as a platform service and should not implement its own tracing infrastructure. - -### `HealthRegistry` - -File: [registry.py](/Users/alex/Dev_projects_v2/apps/plba/src/app_runtime/health/registry.py) - -Aggregates application health. - -PLBA uses three health states: -- `ok` — all critical parts work -- `degraded` — application still works, but there is a problem -- `unhealthy` — application should not be considered operational - -### Runtime status - -File: [types.py](/Users/alex/Dev_projects_v2/apps/plba/src/app_runtime/core/types.py) - -Status is separate from health. - -Current runtime states: -- `starting` -- `idle` -- `busy` -- `stopping` -- `stopped` - -Status is used for operational lifecycle decisions such as graceful shutdown. - -### `ControlPlaneService` - -Files: -- [service.py](/Users/alex/Dev_projects_v2/apps/plba/src/app_runtime/control/service.py) -- [http_channel.py](/Users/alex/Dev_projects_v2/apps/plba/src/app_runtime/control/http_channel.py) - -Provides control and observability endpoints. - -Currently supported: -- health access -- runtime start action -- runtime stop action -- runtime status action - -### `ConfigurationManager` - -Files: -- [configuration.py](/Users/alex/Dev_projects_v2/apps/plba/src/app_runtime/core/configuration.py) -- [file_loader.py](/Users/alex/Dev_projects_v2/apps/plba/src/app_runtime/config/file_loader.py) -- [providers.py](/Users/alex/Dev_projects_v2/apps/plba/src/app_runtime/config/providers.py) - -Loads and merges configuration. - -Current built-in source: -- YAML file provider - -### `LogManager` - -File: [manager.py](/Users/alex/Dev_projects_v2/apps/plba/src/app_runtime/logging/manager.py) - -Applies logging configuration from config. - -Current expectation: -- logging config lives in the `log` section of YAML - -## Available platform services - -PLBA currently provides these reusable services. - -### 1. Runtime lifecycle - -Service: -- `RuntimeManager` - -What it gives: -- startup orchestration -- worker registration and startup -- graceful stop with timeout -- force stop -- status snapshot - -Example use: -- start `mail_order_bot` -- stop it after active email processing is drained - -### 2. Worker supervision - -Service: -- `WorkerSupervisor` - -What it gives: -- unified worker orchestration -- aggregated worker statuses -- aggregated worker health -- stop coordination - -Example use: -- run one polling worker and three processing workers in the same application - -### 3. Queue support - -Services: -- `TaskQueue` -- `InMemoryTaskQueue` -- `QueueWorker` - -What it gives: -- buffered processing -- decoupling between task production and task consumption -- worker concurrency for task handling - -Example use: -- worker A polls IMAP and pushes tasks to queue -- worker B processes queued email tasks with concurrency `3` - -### 4. Configuration - -Services: -- `ConfigurationManager` -- `FileConfigProvider` -- `ConfigFileLoader` - -What it gives: -- YAML config loading -- config merging -- access to platform and application config - -Example use: -- load `platform` section for runtime -- load `mail_order_bot` section for app-specific config - -### 5. Tracing - -Services: -- `TraceService` -- `TraceTransport` -- `NoOpTraceTransport` - -What it gives: -- trace context creation -- trace propagation through task metadata -- trace messages for processing steps - -Example use: -- polling worker creates trace when it discovers a mail -- processing worker resumes trace and writes business steps - -### 6. Health - -Services: -- `HealthRegistry` -- `WorkerHealth` - -What it gives: -- per-worker health -- aggregated application health -- critical vs non-critical component handling - -Example use: -- email processing workers are critical -- optional diagnostic worker may be non-critical - -### 7. Status - -Services: -- `WorkerStatus` -- runtime aggregated state - -What it gives: -- current activity visibility -- ability to stop application only after in-flight work is completed - -Example use: -- stop application only after processing workers become `idle` or `stopped` - -### 8. HTTP control - -Services: -- `ControlPlaneService` -- `HttpControlChannel` - -What it gives: -- HTTP health/status/actions -- operational integration point - -Example use: -- inspect current health from orchestration -- request graceful stop remotely - -## Public package API - -Public namespace is `plba`. - -Main imports for external applications: - -```python -from plba import ApplicationModule, QueueWorker, RuntimeManager, create_runtime -from plba.contracts import Task, TaskHandler, TaskQueue, Worker, WorkerHealth, WorkerStatus -from plba.queue import InMemoryTaskQueue -from plba.tracing import TraceService +## 1. Общее описание сервиса и его назначение + +`PLBA` (`Platform Runtime for Business Applications`) - это платформенный runtime для бизнес-приложений. Библиотека выносит из прикладного кода типовые инфраструктурные задачи: жизненный цикл приложения, запуск и остановку фоновых воркеров, загрузку конфигурации, health-check, tracing, логирование и control plane. + +Назначение сервиса: +- дать единый каркас для запуска бизнес-модулей; +- отделить платформенные обязанности от предметной логики; +- упростить разработку сервисов с очередями, polling-обработчиками и фоновыми процессами; +- обеспечить наблюдаемость и управляемость runtime через health/status и HTTP control endpoints. + +Текущая модель работы выглядит так: +1. приложение создаёт `RuntimeManager`; +2. runtime загружает конфигурацию; +3. применяется logging-конфигурация; +4. модуль приложения регистрирует очереди, обработчики, воркеры и health contributors; +5. `WorkerSupervisor` запускает все рабочие компоненты; +6. runtime агрегирует состояние, health и tracing; +7. control plane предоставляет снимок состояния и команды запуска/остановки. + +`PLBA` особенно полезен для: +- почтовых ботов и интеграционных сервисов; +- event-driven и queue-driven приложений; +- фоновых бизнес-процессов; +- внутренних платформенных сервисов с единым operational-контуром. + +## 2. Архитектура - диаграмма классов + +```mermaid +classDiagram + class RuntimeManager { + +register_module(module) + +add_config_file(path) + +start() + +stop(timeout, force, stop_control_plane) + +status() + +current_health() + } + + class ConfigurationManager { + +add_provider(provider) + +load() + +reload() + +get() + +section(name, default) + } + + class ServiceContainer { + +register(name, service) + +get(name) + +require(name, expected_type) + +snapshot() + } + + class ModuleRegistry { + +register_module(name) + +add_queue(name, queue) + +add_handler(name, handler) + +add_worker(worker) + +add_health_contributor(contributor) + } + + class ApplicationModule { + <> + +name + +register(registry) + } + + class WorkerSupervisor { + +register(worker) + +start() + +stop(timeout, force) + +snapshot() + +healths() + +statuses() + } + + class Worker { + <> + +start() + +stop(force) + +health() + +status() + } + + class QueueWorker { + +name + +critical + +start() + +stop(force) + +health() + +status() + } + + class TaskQueue { + <> + +publish(task) + +consume(timeout) + +ack(task) + +nack(task, retry_delay) + +stats() + } + + class InMemoryTaskQueue { + +publish(task) + +consume(timeout) + +ack(task) + +nack(task, retry_delay) + +stats() + } + + class TaskHandler { + <> + +handle(task) + } + + class TraceService { + +create_context(...) + +open_context(...) + +resume(task_metadata, operation) + +attach(task_metadata, context) + +info(message, status, attrs) + +warning(message, status, attrs) + +error(message, status, attrs) + } + + class HealthRegistry { + +register(contributor) + +snapshot(worker_healths) + +payload(state, worker_healths) + } + + class ControlPlaneService { + +register_channel(channel) + +start(runtime) + +stop() + +snapshot(runtime) + } + + class LogManager { + +apply_config(config) + } + + class FileConfigProvider { + +load() + } + + RuntimeManager --> ConfigurationManager + RuntimeManager --> ServiceContainer + RuntimeManager --> ModuleRegistry + RuntimeManager --> WorkerSupervisor + RuntimeManager --> TraceService + RuntimeManager --> HealthRegistry + RuntimeManager --> ControlPlaneService + RuntimeManager --> LogManager + RuntimeManager --> ApplicationModule + ModuleRegistry --> ServiceContainer + ModuleRegistry --> Worker + ModuleRegistry --> TaskQueue + ModuleRegistry --> TaskHandler + WorkerSupervisor --> Worker + QueueWorker --|> Worker + QueueWorker --> TaskQueue + QueueWorker --> TaskHandler + QueueWorker --> TraceService + InMemoryTaskQueue --|> TaskQueue + ConfigurationManager --> FileConfigProvider ``` -## Example application pattern +### Архитектурные слои -Minimal queue-based application: +- `app_runtime.core` - оркестрация runtime, контейнер сервисов, регистрация модулей, типы состояния. +- `app_runtime.contracts` - абстракции для интеграции бизнес-приложений. +- `app_runtime.workers`, `queue`, `config`, `logging`, `health`, `tracing`, `control` - инфраструктурные адаптеры и платформенные сервисы. +- `plba` - публичный фасад, который реэкспортирует ключевые классы как API пакета. + +## 3. Описание доступных модулей, их назначение, краткое устройство, примеры применения в бизнес приложениях + +### `plba` + +Публичный API пакета. Реэкспортирует `RuntimeManager`, `ApplicationModule`, `QueueWorker`, `InMemoryTaskQueue`, `TraceService`, `HealthRegistry`, `ControlPlaneService` и другие классы. + +Краткое устройство: +- служит фасадом над `app_runtime`; +- упрощает импорт для прикладного кода; +- позволяет использовать пакет как библиотеку без знания внутренней структуры. + +Пример применения: +- бизнес-сервис импортирует `create_runtime` и `ApplicationModule`, собирает свой модуль и запускает runtime. + +### `app_runtime.core` + +Основной orchestration-слой. + +Ключевые классы: +- `RuntimeManager` - центральная точка запуска и остановки; +- `ConfigurationManager` - загрузка и merge конфигурации; +- `ServiceContainer` - DI-like контейнер платформенных сервисов; +- `ModuleRegistry` - регистрация очередей, обработчиков, воркеров и health contributors. + +Краткое устройство: +- `RuntimeManager` создаёт и связывает инфраструктурные сервисы; +- при старте регистрирует health contributors, воркеры и поднимает control plane; +- `ModuleRegistry` связывает бизнес-модуль с runtime без жёсткой зависимости на конкретные реализации. + +Примеры применения в бизнес-приложениях: +- CRM-интеграция с несколькими фоновых воркерами; +- сервис обработки заявок, где один модуль регистрирует очередь, handler и worker pool; +- back-office процесс с управляемым graceful shutdown. + +### `app_runtime.contracts` + +Набор абстракций для расширения платформы. + +Ключевые контракты: +- `ApplicationModule`; +- `Worker`; +- `TaskQueue`; +- `TaskHandler`; +- `ConfigProvider`; +- `HealthContributor`; +- trace-related контракты. + +Краткое устройство: +- бизнес-код реализует интерфейсы, а runtime работает только через контракты; +- это позволяет менять инфраструктуру без переписывания прикладной логики. + +Примеры применения в бизнес-приложениях: +- реализовать свой `ApplicationModule` для почтового бота; +- подключить собственный `ConfigProvider` для БД или secrets storage; +- реализовать кастомный `Worker` для long-running polling процесса. + +### `app_runtime.workers` + +Модуль управления рабочими процессами. + +Ключевые классы: +- `WorkerSupervisor` - запускает и останавливает набор воркеров; +- `QueueWorker` - стандартный worker для обработки задач из очереди. + +Краткое устройство: +- `WorkerSupervisor` агрегирует health/status всех воркеров; +- `QueueWorker` поднимает нужное число потоков, читает задачи из `TaskQueue`, вызывает `TaskHandler`, делает `ack/nack` и обновляет operational-метрики. + +Примеры применения в бизнес-приложениях: +- параллельная обработка входящих писем; +- обработка очереди заказов; +- фоновая генерация документов или актов. + +### `app_runtime.queue` + +Очереди задач. + +Ключевой класс: +- `InMemoryTaskQueue`. + +Краткое устройство: +- использует стандартный `Queue` из Python; +- хранит счётчики `published`, `acked`, `nacked`, `queued`; +- подходит как базовая реализация для разработки, тестов и простых сценариев. + +Примеры применения в бизнес-приложениях: +- локальная очередь задач в небольшом внутреннем сервисе; +- тестовая среда без внешнего брокера; +- staging-сценарии для отладки worker pipeline. + +### `app_runtime.config` + +Подсистема загрузки конфигурации. + +Ключевые классы: +- `FileConfigProvider`; +- `ConfigFileLoader`. + +Краткое устройство: +- `ConfigurationManager` собирает данные из провайдеров; +- текущая штатная реализация читает YAML-файл; +- поддерживается глубокое слияние секций конфигурации. + +Примеры применения в бизнес-приложениях: +- конфигурация платформы и прикладных модулей из `config.yml`; +- раздельное хранение `platform`, `log` и app-specific секций; +- подключение нескольких источников конфигурации с последующим merge. + +### `app_runtime.logging` + +Управление логированием. + +Ключевой класс: +- `LogManager`. + +Краткое устройство: +- применяет `dictConfig` из секции `log`; +- хранит последнюю валидную конфигурацию и пытается восстановиться при ошибке. + +Примеры применения в бизнес-приложениях: +- единообразная настройка JSON-логов; +- переключение уровней логирования между окружениями; +- централизованная logging-конфигурация для нескольких модулей. + +### `app_runtime.health` + +Подсистема health aggregation. + +Ключевой класс: +- `HealthRegistry`. + +Краткое устройство: +- собирает health от воркеров и дополнительных contributors; +- агрегирует статус в `ok`, `degraded`, `unhealthy`; +- формирует payload для readiness/liveness и operational snapshot. + +Примеры применения в бизнес-приложениях: +- показывать degraded, если обработка идёт с ошибками; +- маркировать сервис unhealthy при падении критичного worker; +- добавлять health внешней зависимости, например IMAP или ERP API. + +### `app_runtime.tracing` + +Подсистема трассировки выполнения. + +Ключевые классы: +- `TraceService`; +- `TraceContextStore`; +- `NoOpTraceTransport`. + +Краткое устройство: +- создаёт trace contexts; +- связывает source/queue/worker/handler через metadata; +- пишет контексты и сообщения через транспортный слой. + +Примеры применения в бизнес-приложениях: +- трассировка обработки письма от polling до бизнес-handler; +- аудит прохождения заказа по pipeline; +- отладка проблемных задач в фоне. + +### `app_runtime.control` + +Control plane и HTTP-канал управления. + +Ключевые классы: +- `ControlPlaneService`; +- `HttpControlChannel`; +- `ControlActionSet`. + +Краткое устройство: +- публикует health/status и команды управления runtime; +- может поднимать HTTP endpoints для start/stop/status; +- строит snapshot состояния на основе `RuntimeManager`. + +Примеры применения в бизнес-приложениях: +- административный endpoint для оператора; +- health endpoint для Kubernetes/nomad; +- runtime status для monitoring dashboard. + +## 4. Установка - `git@git.lesha.spb.ru:alex/plba.git` + +### Требования + +- Python `3.12+` +- `pip` +- SSH-доступ к `git.lesha.spb.ru` + +### Установка напрямую через `pip` из Git-репозитория + +```bash +pip install "plba @ git+ssh://git@git.lesha.spb.ru/alex/plba.git" +``` + +Если нужна установка из конкретной ветки: + +```bash +pip install "plba @ git+ssh://git@git.lesha.spb.ru/alex/plba.git@main" +``` + +Если нужна установка из конкретного тега или commit hash: + +```bash +pip install "plba @ git+ssh://git@git.lesha.spb.ru/alex/plba.git@v0.1.0" +``` + +или + +```bash +pip install "plba @ git+ssh://git@git.lesha.spb.ru/alex/plba.git@" +``` + +### Установка в виртуальное окружение + +```bash +python -m venv .venv +source .venv/bin/activate +pip install --upgrade pip +pip install "plba @ git+ssh://git@git.lesha.spb.ru/alex/plba.git" +``` + +### Локальная разработка + +Если пакет нужно не только использовать, но и разрабатывать: + +```bash +git clone git@git.lesha.spb.ru:alex/plba.git +cd plba +python -m venv .venv +source .venv/bin/activate +pip install -e . +``` + +### Быстрая проверка + +```bash +python -c "import plba; print(plba.__all__[:5])" +``` + +### Минимальный пример использования ```python -from plba import ApplicationModule, QueueWorker, Task, TaskHandler, create_runtime -from plba.queue import InMemoryTaskQueue +from plba import ApplicationModule, InMemoryTaskQueue, QueueWorker, RuntimeManager, Task, TaskHandler -class ExampleHandler(TaskHandler): +class PrintHandler(TaskHandler): def handle(self, task: Task) -> None: print(task.payload) -class ExampleModule(ApplicationModule): +class DemoModule(ApplicationModule): @property def name(self) -> str: - return "example" + return "demo" def register(self, registry) -> None: queue = InMemoryTaskQueue() traces = registry.services.get("traces") - - queue.publish(Task(name="incoming", payload={"hello": "world"})) - - registry.add_queue("incoming", queue) - registry.add_worker(QueueWorker("example-worker", queue, ExampleHandler(), traces)) + handler = PrintHandler() + queue.publish(Task(name="demo-task", payload={"id": 1}, metadata={})) + registry.add_worker(QueueWorker("demo-worker", queue, handler, traces)) -runtime = create_runtime( - ExampleModule(), - config_path="config.yml", - enable_http_control=False, -) +runtime = RuntimeManager() +runtime.register_module(DemoModule()) runtime.start() +runtime.stop() ``` - -## Building business applications on PLBA - -These are the current rules for building business applications correctly. - -### 1. Keep platform and business concerns separate - -PLBA owns: -- lifecycle -- worker management -- logging -- trace infrastructure -- health aggregation -- HTTP control -- config loading - -Business application owns: -- business workflows -- domain services -- application-specific config schema -- business task payloads -- business error semantics - -### 2. Build app behavior from workers - -A business application should be described as a small set of workers. - -Typical examples: -- polling worker -- processing worker -- reconciliation worker - -Do not introduce new worker types at platform level unless there is clear need for custom runtime behavior. - -### 3. Use queues only when they help - -Queue is optional. - -Use queue when: -- one worker discovers work -- another worker processes it -- buffering or decoupling helps -- concurrency is needed - -Do not force queue into applications that do not need it. - -### 4. Keep business logic out of worker lifecycle code - -Worker should orchestrate execution. -Business rules should live in dedicated services and handlers. - -Good: -- worker gets config -- worker calls domain service -- worker reports trace and status - -Bad: -- worker contains all parsing, decision logic, integration rules, and persistence rules in one class - -### 5. Use trace as a platform service - -Business application should: -- create meaningful trace steps -- propagate trace through task metadata if queue is used -- record business-relevant processing milestones - -Business application should not: -- implement its own trace store -- control trace transport directly unless explicitly needed - -### 6. Read config through PLBA - -Business application should not read YAML directly. - -Recommended flow: -- PLBA loads config -- application reads only its own config section -- application converts it to typed app config object -- services receive typed config object - -### 7. Distinguish health from status - -Use `health` for: -- is application operational? - -Use `status` for: -- what is application doing right now? - -This is important for graceful stop: -- health may still be `ok` -- status may be `busy` - -### 8. Design workers for graceful stop - -Workers should support: -- stop accepting new work -- finish current in-flight work when possible -- report `busy`, `idle`, `stopping`, `stopped` - -This allows runtime to stop application safely. - -## Recommended repository model - -PLBA is intended to live in its own repository as a reusable package. - -Recommended setup: -- repository `plba`: platform package only -- repository `mail_order_bot`: business application depending on `plba` -- repository `service_b`: business application depending on `plba` - -## Example: `mail_order_bot` - -Simple first version of `mail_order_bot` on PLBA: -- `MailPollingWorker`, concurrency `1` -- `EmailProcessingWorker`, concurrency `3` -- shared `InMemoryTaskQueue` -- domain services for mail parsing and order processing - -Flow: -1. polling worker checks IMAP -2. polling worker pushes email tasks into queue -3. processing workers consume tasks -4. processing workers execute domain logic -5. runtime aggregates health and status - -This keeps `mail_order_bot` small, explicit, and aligned with current PLBA architecture. diff --git a/Architectural constraints.md b/requirements/Architectural constraints.md similarity index 100% rename from Architectural constraints.md rename to requirements/Architectural constraints.md diff --git a/Mail Order Bot Migration Plan.md b/requirements/Mail Order Bot Migration Plan.md similarity index 100% rename from Mail Order Bot Migration Plan.md rename to requirements/Mail Order Bot Migration Plan.md diff --git a/requirements/README.md b/requirements/README.md new file mode 100644 index 0000000..5a6c2a7 --- /dev/null +++ b/requirements/README.md @@ -0,0 +1,469 @@ +# PLBA + +`PLBA` is a reusable platform runtime for business applications. + +It solves platform concerns that should not live inside domain code: +- application lifecycle +- worker orchestration +- configuration loading from YAML +- tracing +- health aggregation +- runtime status reporting +- HTTP control endpoints +- logging configuration + +Business applications depend on `plba` as a package and implement only their own business behavior. + +## Architecture + +Current PLBA architecture is built around one core idea: +- the runtime manages a set of application workers + +A worker is any runtime-managed active component with a unified lifecycle: +- `start()` +- `stop(force=False)` +- `health()` +- `status()` + +This means PLBA does not require separate platform categories like `source` and `consumer`. +If an application needs polling, queue processing, listening, scheduled work, or another active loop, it is implemented as a worker. + +### Main runtime model + +1. application creates `RuntimeManager` +2. runtime loads configuration +3. runtime applies logging configuration +4. application module registers workers and supporting services +5. runtime starts all workers +6. workers execute business-related loops or processing +7. runtime aggregates health and status +8. runtime stops workers gracefully or forcefully + +## Core concepts + +### `ApplicationModule` + +File: [application.py](/Users/alex/Dev_projects_v2/apps/plba/src/app_runtime/contracts/application.py) + +Describes a business application to the runtime. + +Responsibilities: +- provide module name +- register workers +- register queues if needed +- register handlers if needed +- register health contributors +- compose application-specific objects + +`ApplicationModule` does not run the application itself. +It only declares how the application is assembled. + +### `Worker` + +File: [worker.py](/Users/alex/Dev_projects_v2/apps/plba/src/app_runtime/contracts/worker.py) + +The main runtime-managed contract. + +Responsibilities: +- start its own execution +- stop gracefully or forcefully +- report health +- report runtime status + +This is the main extension point for business applications. + +### `TaskQueue` + +File: [queue.py](/Users/alex/Dev_projects_v2/apps/plba/src/app_runtime/contracts/queue.py) + +Optional queue abstraction. + +Use it when application workers need buffered or decoupled processing. + +PLBA does not force every application to use a queue. +Queue is one supported pattern, not the foundation of the whole platform. + +### `TaskHandler` + +File: [tasks.py](/Users/alex/Dev_projects_v2/apps/plba/src/app_runtime/contracts/tasks.py) + +Optional unit of business processing for one task. + +Useful when a worker follows queue-driven logic: +- worker takes a task +- handler executes business logic + +### `TraceService` + +File: [service.py](/Users/alex/Dev_projects_v2/apps/plba/src/app_runtime/tracing/service.py) + +Platform trace service. + +Responsibilities: +- create trace contexts +- resume trace from task metadata +- write context records +- write trace messages + +Business code should use it as a platform service and should not implement its own tracing infrastructure. + +### `HealthRegistry` + +File: [registry.py](/Users/alex/Dev_projects_v2/apps/plba/src/app_runtime/health/registry.py) + +Aggregates application health. + +PLBA uses three health states: +- `ok` — all critical parts work +- `degraded` — application still works, but there is a problem +- `unhealthy` — application should not be considered operational + +### Runtime status + +File: [types.py](/Users/alex/Dev_projects_v2/apps/plba/src/app_runtime/core/types.py) + +Status is separate from health. + +Current runtime states: +- `starting` +- `idle` +- `busy` +- `stopping` +- `stopped` + +Status is used for operational lifecycle decisions such as graceful shutdown. + +### `ControlPlaneService` + +Files: +- [service.py](/Users/alex/Dev_projects_v2/apps/plba/src/app_runtime/control/service.py) +- [http_channel.py](/Users/alex/Dev_projects_v2/apps/plba/src/app_runtime/control/http_channel.py) + +Provides control and observability endpoints. + +Currently supported: +- health access +- runtime start action +- runtime stop action +- runtime status action + +### `ConfigurationManager` + +Files: +- [configuration.py](/Users/alex/Dev_projects_v2/apps/plba/src/app_runtime/core/configuration.py) +- [file_loader.py](/Users/alex/Dev_projects_v2/apps/plba/src/app_runtime/config/file_loader.py) +- [providers.py](/Users/alex/Dev_projects_v2/apps/plba/src/app_runtime/config/providers.py) + +Loads and merges configuration. + +Current built-in source: +- YAML file provider + +### `LogManager` + +File: [manager.py](/Users/alex/Dev_projects_v2/apps/plba/src/app_runtime/logging/manager.py) + +Applies logging configuration from config. + +Current expectation: +- logging config lives in the `log` section of YAML + +## Available platform services + +PLBA currently provides these reusable services. + +### 1. Runtime lifecycle + +Service: +- `RuntimeManager` + +What it gives: +- startup orchestration +- worker registration and startup +- graceful stop with timeout +- force stop +- status snapshot + +Example use: +- start `mail_order_bot` +- stop it after active email processing is drained + +### 2. Worker supervision + +Service: +- `WorkerSupervisor` + +What it gives: +- unified worker orchestration +- aggregated worker statuses +- aggregated worker health +- stop coordination + +Example use: +- run one polling worker and three processing workers in the same application + +### 3. Queue support + +Services: +- `TaskQueue` +- `InMemoryTaskQueue` +- `QueueWorker` + +What it gives: +- buffered processing +- decoupling between task production and task consumption +- worker concurrency for task handling + +Example use: +- worker A polls IMAP and pushes tasks to queue +- worker B processes queued email tasks with concurrency `3` + +### 4. Configuration + +Services: +- `ConfigurationManager` +- `FileConfigProvider` +- `ConfigFileLoader` + +What it gives: +- YAML config loading +- config merging +- access to platform and application config + +Example use: +- load `platform` section for runtime +- load `mail_order_bot` section for app-specific config + +### 5. Tracing + +Services: +- `TraceService` +- `TraceTransport` +- `NoOpTraceTransport` + +What it gives: +- trace context creation +- trace propagation through task metadata +- trace messages for processing steps + +Example use: +- polling worker creates trace when it discovers a mail +- processing worker resumes trace and writes business steps + +### 6. Health + +Services: +- `HealthRegistry` +- `WorkerHealth` + +What it gives: +- per-worker health +- aggregated application health +- critical vs non-critical component handling + +Example use: +- email processing workers are critical +- optional diagnostic worker may be non-critical + +### 7. Status + +Services: +- `WorkerStatus` +- runtime aggregated state + +What it gives: +- current activity visibility +- ability to stop application only after in-flight work is completed + +Example use: +- stop application only after processing workers become `idle` or `stopped` + +### 8. HTTP control + +Services: +- `ControlPlaneService` +- `HttpControlChannel` + +What it gives: +- HTTP health/status/actions +- operational integration point + +Example use: +- inspect current health from orchestration +- request graceful stop remotely + +## Public package API + +Public namespace is `plba`. + +Main imports for external applications: + +```python +from plba import ApplicationModule, QueueWorker, RuntimeManager, create_runtime +from plba.contracts import Task, TaskHandler, TaskQueue, Worker, WorkerHealth, WorkerStatus +from plba.queue import InMemoryTaskQueue +from plba.tracing import TraceService +``` + +## Example application pattern + +Minimal queue-based application: + +```python +from plba import ApplicationModule, QueueWorker, Task, TaskHandler, create_runtime +from plba.queue import InMemoryTaskQueue + + +class ExampleHandler(TaskHandler): + def handle(self, task: Task) -> None: + print(task.payload) + + +class ExampleModule(ApplicationModule): + @property + def name(self) -> str: + return "example" + + def register(self, registry) -> None: + queue = InMemoryTaskQueue() + traces = registry.services.get("traces") + + queue.publish(Task(name="incoming", payload={"hello": "world"})) + + registry.add_queue("incoming", queue) + registry.add_worker(QueueWorker("example-worker", queue, ExampleHandler(), traces)) + + +runtime = create_runtime( + ExampleModule(), + config_path="config.yml", + enable_http_control=False, +) +runtime.start() +``` + +## Building business applications on PLBA + +These are the current rules for building business applications correctly. + +### 1. Keep platform and business concerns separate + +PLBA owns: +- lifecycle +- worker management +- logging +- trace infrastructure +- health aggregation +- HTTP control +- config loading + +Business application owns: +- business workflows +- domain services +- application-specific config schema +- business task payloads +- business error semantics + +### 2. Build app behavior from workers + +A business application should be described as a small set of workers. + +Typical examples: +- polling worker +- processing worker +- reconciliation worker + +Do not introduce new worker types at platform level unless there is clear need for custom runtime behavior. + +### 3. Use queues only when they help + +Queue is optional. + +Use queue when: +- one worker discovers work +- another worker processes it +- buffering or decoupling helps +- concurrency is needed + +Do not force queue into applications that do not need it. + +### 4. Keep business logic out of worker lifecycle code + +Worker should orchestrate execution. +Business rules should live in dedicated services and handlers. + +Good: +- worker gets config +- worker calls domain service +- worker reports trace and status + +Bad: +- worker contains all parsing, decision logic, integration rules, and persistence rules in one class + +### 5. Use trace as a platform service + +Business application should: +- create meaningful trace steps +- propagate trace through task metadata if queue is used +- record business-relevant processing milestones + +Business application should not: +- implement its own trace store +- control trace transport directly unless explicitly needed + +### 6. Read config through PLBA + +Business application should not read YAML directly. + +Recommended flow: +- PLBA loads config +- application reads only its own config section +- application converts it to typed app config object +- services receive typed config object + +### 7. Distinguish health from status + +Use `health` for: +- is application operational? + +Use `status` for: +- what is application doing right now? + +This is important for graceful stop: +- health may still be `ok` +- status may be `busy` + +### 8. Design workers for graceful stop + +Workers should support: +- stop accepting new work +- finish current in-flight work when possible +- report `busy`, `idle`, `stopping`, `stopped` + +This allows runtime to stop application safely. + +## Recommended repository model + +PLBA is intended to live in its own repository as a reusable package. + +Recommended setup: +- repository `plba`: platform package only +- repository `mail_order_bot`: business application depending on `plba` +- repository `service_b`: business application depending on `plba` + +## Example: `mail_order_bot` + +Simple first version of `mail_order_bot` on PLBA: +- `MailPollingWorker`, concurrency `1` +- `EmailProcessingWorker`, concurrency `3` +- shared `InMemoryTaskQueue` +- domain services for mail parsing and order processing + +Flow: +1. polling worker checks IMAP +2. polling worker pushes email tasks into queue +3. processing workers consume tasks +4. processing workers execute domain logic +5. runtime aggregates health and status + +This keeps `mail_order_bot` small, explicit, and aligned with current PLBA architecture. diff --git a/architecture.md b/requirements/architecture.md similarity index 100% rename from architecture.md rename to requirements/architecture.md diff --git a/vision.md b/requirements/vision.md similarity index 100% rename from vision.md rename to requirements/vision.md