Перенес workflow
This commit is contained in:
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user