Перенес workflow
This commit is contained in:
148
requirements/application_guidelines.md
Normal file
148
requirements/application_guidelines.md
Normal file
@@ -0,0 +1,148 @@
|
||||
# Application Guidelines
|
||||
|
||||
## Purpose
|
||||
|
||||
This document defines the default rules for building business applications on top of `plba`.
|
||||
|
||||
The goal is to keep applications:
|
||||
- explicit
|
||||
- small
|
||||
- easy to debug
|
||||
- free from platform legacy artifacts
|
||||
|
||||
## Main model
|
||||
|
||||
Build every application around this chain:
|
||||
|
||||
`ApplicationModule` -> `Worker` -> business `Routine`
|
||||
|
||||
Meaning:
|
||||
- `ApplicationModule` assembles the application
|
||||
- `Worker` owns runtime execution and lifecycle
|
||||
- `Routine` owns business behavior
|
||||
|
||||
`Routine` is an application pattern, not a mandatory platform contract.
|
||||
|
||||
## Rules
|
||||
|
||||
### 1. Assemble the app in `ApplicationModule`
|
||||
|
||||
`ApplicationModule` should:
|
||||
- create application services
|
||||
- create routines
|
||||
- create workers
|
||||
- register workers
|
||||
- register optional health contributors
|
||||
|
||||
`ApplicationModule` should not:
|
||||
- execute business logic itself
|
||||
- contain runtime loops
|
||||
|
||||
### 2. Treat `Worker` as the only primary runtime abstraction
|
||||
|
||||
`Worker` is the core runtime contract of the platform.
|
||||
|
||||
Worker should own:
|
||||
- `start()`
|
||||
- `stop(force=False)`
|
||||
- `health()`
|
||||
- `status()`
|
||||
- thread ownership
|
||||
- execution strategy
|
||||
- graceful shutdown
|
||||
|
||||
Worker should not own:
|
||||
- large business flows
|
||||
- domain decisions
|
||||
- parsing, persistence, and integration rules all mixed together
|
||||
|
||||
### 3. Keep one worker focused on one business activity
|
||||
|
||||
Default recommendation:
|
||||
- one worker -> one routine
|
||||
|
||||
If a process has multiple distinct behaviors:
|
||||
- split it into multiple workers
|
||||
- or compose several services behind one focused routine
|
||||
|
||||
Do not make a worker a container for unrelated business scenarios.
|
||||
|
||||
### 4. Put business logic into routines and services
|
||||
|
||||
Routine should contain:
|
||||
- business flow steps
|
||||
- domain service calls
|
||||
- business validation
|
||||
- integration calls
|
||||
- persistence orchestration
|
||||
|
||||
If the routine becomes too large:
|
||||
- split business logic into dedicated services
|
||||
- keep routine as a thin application-level orchestrator
|
||||
|
||||
### 5. Let the worker define the run model
|
||||
|
||||
The worker decides:
|
||||
- single-run or loop
|
||||
- one thread or multiple threads
|
||||
- interval between iterations
|
||||
- batch or long-running mode
|
||||
- stop conditions
|
||||
|
||||
The routine does not decide lifecycle strategy.
|
||||
|
||||
### 6. Let the worker compute health
|
||||
|
||||
Routine should not directly set platform health state.
|
||||
|
||||
Instead:
|
||||
- routine completes successfully
|
||||
- or returns outcome information
|
||||
- or raises typed exceptions
|
||||
|
||||
Then worker interprets that into:
|
||||
- `ok`
|
||||
- `degraded`
|
||||
- `unhealthy`
|
||||
|
||||
### 7. Use queues only as optional app-level utilities
|
||||
|
||||
`InMemoryTaskQueue` may be used inside an application when buffering helps.
|
||||
|
||||
But:
|
||||
- queue is not a core platform concept
|
||||
- queue usage should stay a local implementation choice
|
||||
- the app should still be described through workers and routines
|
||||
|
||||
### 8. Keep tracing vocabulary neutral
|
||||
|
||||
Use tracing to describe operations and execution context, not legacy architectural roles.
|
||||
|
||||
Prefer terms like:
|
||||
- operation
|
||||
- worker
|
||||
- routine
|
||||
- metadata
|
||||
- step
|
||||
|
||||
Avoid making trace terminology define the application architecture.
|
||||
|
||||
### 9. Keep classes small and responsibilities clear
|
||||
|
||||
Preferred shape:
|
||||
- thin `ApplicationModule`
|
||||
- thin `Worker`
|
||||
- focused `Routine`
|
||||
- dedicated domain services
|
||||
|
||||
If a class grows too much, split it by responsibility instead of adding more platform abstractions.
|
||||
|
||||
## Checklist
|
||||
|
||||
Before adding a new application component, check:
|
||||
|
||||
1. Is this runtime behavior or business behavior?
|
||||
2. If runtime behavior, should it live in a `Worker`?
|
||||
3. If business behavior, should it live in a `Routine` or service?
|
||||
4. Does this component stay small and single-purpose?
|
||||
5. Am I adding a queue because it is useful, or because of old mental models?
|
||||
Reference in New Issue
Block a user