3.5 KiB
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:
ApplicationModuleassembles the applicationWorkerowns runtime execution and lifecycleRoutineowns 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:
okdegradedunhealthy
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:
- Is this runtime behavior or business behavior?
- If runtime behavior, should it live in a
Worker? - If business behavior, should it live in a
Routineor service? - Does this component stay small and single-purpose?
- Am I adding a queue because it is useful, or because of old mental models?