Перенес workflow

This commit is contained in:
2026-03-05 11:46:05 +03:00
parent 4a0646bb14
commit 89c0d21e88
65 changed files with 1271 additions and 1640 deletions

View File

@@ -2,247 +2,130 @@
## Overview
The runtime is built as a platform layer for business applications.
It consists of four logical layers:
PLBA consists of four logical layers:
- platform core
- platform contracts
- infrastructure adapters
- infrastructure services
- business applications
The runtime is centered on `Worker`.
## Layers
### Platform core
The core contains long-lived runtime services:
Core services:
- `RuntimeManager`
- `ConfigurationManager`
- `WorkerSupervisor`
- `TraceService`
- `HealthRegistry`
- `ControlPlaneService`
- `ServiceContainer`
The core is responsible for orchestration, not domain behavior.
### Platform contracts
Contracts define how business applications integrate with the runtime.
Main contracts:
- `ApplicationModule`
- `TaskSource`
- `TaskQueue`
- `Worker`
- `TaskHandler`
- `ConfigProvider`
- `HealthContributor`
- `TraceFactory`
These contracts must remain domain-agnostic.
### Infrastructure adapters
Adapters implement concrete runtime capabilities:
- in-memory queue
- Redis queue
- file config loader
- database config loader
- polling source
- IMAP IDLE source
- HTTP control plane
- trace transport adapters
Adapters may change between applications and deployments.
### Business applications
Applications are built on top of the contracts and adapters.
Examples:
- `mail_order_bot`
- future event-driven business services
Applications contain:
- domain models
- domain handlers
- application-specific configuration schema
- source/handler composition
## Core runtime components
### RuntimeManager
The main platform facade.
Responsibilities:
- bootstrap runtime
- initialize services
- register application modules
- start and stop all runtime-managed components
- expose status
- coordinate graceful shutdown
- wire core services
- register modules
- start and stop workers
- expose runtime snapshot
### ConfigurationManager
### Platform contracts
Responsibilities:
- load configuration
- validate configuration
- publish config updates
- provide typed config access
- notify subscribers on reload
Main contracts:
- `ApplicationModule`
- `Worker`
- `ConfigProvider`
- `HealthContributor`
- tracing contracts
Configuration should be divided into:
- platform config
- application config
- environment/runtime overrides
These contracts must remain domain-agnostic.
### WorkerSupervisor
### Infrastructure services
Responsibilities:
- register worker definitions
- start worker pools
- monitor worker health
- restart failed workers when appropriate
- manage parallelism and backpressure
- expose worker-level status
Platform services include:
- tracing
- health registry
- logging manager
- control plane
- config providers
- `InMemoryTaskQueue` as optional utility
### TraceService
### Business applications
Responsibilities:
- create traces for operations
- propagate trace context across source -> queue -> worker -> handler boundaries
- provide trace factories to applications
- remain transport-agnostic
Applications define:
- routines
- domain services
- custom worker implementations
- typed app config
### HealthRegistry
Responsibilities:
- collect health from registered contributors
- aggregate health into liveness/readiness/status views
- expose structured runtime health
### ControlPlaneService
Responsibilities:
- control endpoints
- runtime state visibility
- administrative actions
- later authentication and user/session-aware access
## Main runtime model
The runtime should operate on this conceptual flow:
## Runtime flow
1. runtime starts
2. configuration is loaded
3. services are initialized
4. application modules register sources, queues, handlers, and workers
5. task sources start producing tasks
6. tasks are published into queues
7. workers consume tasks
8. handlers execute business logic
9. traces and health are updated throughout the flow
10. runtime stops gracefully on request
3. core services become available
4. application modules register workers
5. workers start execution
6. workers call business routines
7. runtime aggregates health and status
8. runtime stops workers on request
## Contracts
## Worker model
### ApplicationModule
Worker is responsible for runtime behavior:
- execution strategy
- thread ownership
- graceful shutdown
- runtime status
- health interpretation
Describes a business application to the runtime.
Routine is responsible for business behavior:
- business decisions
- domain orchestration
- persistence and integrations
Responsibilities:
- register domain services
- register task sources
- register queues
- register worker pools
- register handlers
- declare config requirements
- optionally register health contributors
Recommended shape:
### TaskSource
```python
class SomeWorker(Worker):
def __init__(self, routine) -> None:
self._routine = routine
Produces tasks into queues.
def start(self) -> None:
...
Examples:
- IMAP polling source
- IMAP IDLE source
- webhook source
- scheduled source
def stop(self, force: bool = False) -> None:
...
Responsibilities:
- start
- stop
- publish tasks
- expose source status
def health(self) -> WorkerHealth:
...
### TaskQueue
def status(self) -> WorkerStatus:
...
```
A queue abstraction.
## Design rules
Expected operations:
- `publish(task)`
- `consume()`
- `ack(task)`
- `nack(task, retry_delay=None)`
- `stats()`
### 1. Runtime should not know business semantics
The first implementation may be in-memory, but the interface should support future backends.
PLBA knows:
- worker started
- worker stopped
- routine succeeded
- routine failed
### Worker
PLBA does not know:
- what the business operation means
- which domain decision was made
Consumes tasks from a queue and passes them to a handler.
### 2. Queue is not a core architecture primitive
Responsibilities:
- obtain task from queue
- open or resume trace context
- call business handler
- ack or nack the task
- expose worker state
Queues may exist inside applications as implementation details.
### TaskHandler
They must not define the platform mental model.
Executes business logic for one task.
### 3. Keep components small
The runtime should not know what the handler does.
It only knows that a task is processed.
Prefer:
- thin workers
- focused routines
- dedicated domain services
## Mail Order Bot as first application
### Phase 1
- source: IMAP polling
- queue: in-memory queue
- workers: parallel email processing workers
- handler: domain email processing handler
- mark message as read only after successful processing
### Phase 2
- source changes from polling to IMAP IDLE
- queue and workers remain the same
This demonstrates one of the architectural goals:
the source can change without redesigning the rest of the processing pipeline.
## Suggested package structure
```text
src/
app_runtime/
core/
contracts/
config/
workers/
queue/
tracing/
health/
control/
container/
adapters/
mail_order_bot_app/
module/
sources/
handlers/
services/
domain/
Avoid large platform abstractions that exist only for hypothetical reuse.