249 lines
4.9 KiB
Markdown
249 lines
4.9 KiB
Markdown
# Architecture
|
|
|
|
## Overview
|
|
|
|
The runtime is built as a platform layer for business applications.
|
|
|
|
It consists of four logical layers:
|
|
- platform core
|
|
- platform contracts
|
|
- infrastructure adapters
|
|
- business applications
|
|
|
|
## Layers
|
|
|
|
### Platform core
|
|
|
|
The core contains long-lived runtime 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
|
|
|
|
### ConfigurationManager
|
|
|
|
Responsibilities:
|
|
- load configuration
|
|
- validate configuration
|
|
- publish config updates
|
|
- provide typed config access
|
|
- notify subscribers on reload
|
|
|
|
Configuration should be divided into:
|
|
- platform config
|
|
- application config
|
|
- environment/runtime overrides
|
|
|
|
### WorkerSupervisor
|
|
|
|
Responsibilities:
|
|
- register worker definitions
|
|
- start worker pools
|
|
- monitor worker health
|
|
- restart failed workers when appropriate
|
|
- manage parallelism and backpressure
|
|
- expose worker-level status
|
|
|
|
### TraceService
|
|
|
|
Responsibilities:
|
|
- create traces for operations
|
|
- propagate trace context across source -> queue -> worker -> handler boundaries
|
|
- provide trace factories to applications
|
|
- remain transport-agnostic
|
|
|
|
### 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:
|
|
|
|
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
|
|
|
|
## Contracts
|
|
|
|
### ApplicationModule
|
|
|
|
Describes a business application to the runtime.
|
|
|
|
Responsibilities:
|
|
- register domain services
|
|
- register task sources
|
|
- register queues
|
|
- register worker pools
|
|
- register handlers
|
|
- declare config requirements
|
|
- optionally register health contributors
|
|
|
|
### TaskSource
|
|
|
|
Produces tasks into queues.
|
|
|
|
Examples:
|
|
- IMAP polling source
|
|
- IMAP IDLE source
|
|
- webhook source
|
|
- scheduled source
|
|
|
|
Responsibilities:
|
|
- start
|
|
- stop
|
|
- publish tasks
|
|
- expose source status
|
|
|
|
### TaskQueue
|
|
|
|
A queue abstraction.
|
|
|
|
Expected operations:
|
|
- `publish(task)`
|
|
- `consume()`
|
|
- `ack(task)`
|
|
- `nack(task, retry_delay=None)`
|
|
- `stats()`
|
|
|
|
The first implementation may be in-memory, but the interface should support future backends.
|
|
|
|
### Worker
|
|
|
|
Consumes tasks from a queue and passes them to a handler.
|
|
|
|
Responsibilities:
|
|
- obtain task from queue
|
|
- open or resume trace context
|
|
- call business handler
|
|
- ack or nack the task
|
|
- expose worker state
|
|
|
|
### TaskHandler
|
|
|
|
Executes business logic for one task.
|
|
|
|
The runtime should not know what the handler does.
|
|
It only knows that a task is processed.
|
|
|
|
## 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/
|