fix: address design review ACT NOW items (6 risk gaps)

- Add migrate_config() to ConfigGenerator protocol for schema version upgrades
- Add per-server operation lock to ProcessManager to prevent start/stop races
- Add busy_timeout retry/backoff strategy (exponential: 1s, 2s, 4s) for DB lock exhaustion
- Add ConfigForm testing strategy and error boundary for malformed schemas
- Add schema cache invalidation on adapter version change
- Add ConfigMigrationError to typed adapter exceptions
This commit is contained in:
Tran G. (Revernomad) Khoa
2026-04-16 17:29:19 +07:00
parent 624d7594e2
commit b17d199301
6 changed files with 94 additions and 4 deletions

View File

@@ -6,6 +6,7 @@
- WAL mode enabled: `PRAGMA journal_mode=WAL` — allows concurrent reads during writes
- Foreign keys enabled: `PRAGMA foreign_keys=ON`
- Busy timeout: `PRAGMA busy_timeout=5000` — prevents "database is locked" errors under concurrent thread writes
- **Retry on exhaustion**: If busy_timeout is exceeded (5s), writes fail with `OperationalError("database is locked")`. Background threads retry with exponential backoff (1s, 2s, 4s), then skip the tick. API handlers retry up to 2 times with 1s backoff, then return 503. See THREADING.md for the full retry implementation.
---
@@ -537,7 +538,17 @@ The `config_version` column in `game_configs` prevents lost updates when two adm
4. If match: increment version, write new JSON, return 200
5. If no match (version changed): return **409 Conflict** with current config for client-side merge
## game_data JSON Schema
## Config Schema Migration
When the adapter is updated and `get_config_version()` returns a newer version than what's stored in `game_configs.schema_version`, the core automatically migrates:
1. On read, detect `stored_schema_version != adapter.get_config_version()`
2. Call `adapter.migrate_config(stored_schema_version, config_json)` → returns migrated dict
3. Update the row: `SET config_json = ?, schema_version = ? WHERE id = ?`
4. On `ConfigMigrationError`: keep original config, log warning, server runs with old schema
5. Migration is per-section — each section can have a different stored version
This ensures config data is always compatible with the current adapter without manual intervention.
The `game_data` columns on `players`, `missions`, `mods`, and `bans` are validated by adapter-provided Pydantic models. Each capability protocol optionally provides a schema: