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

@@ -281,10 +281,14 @@ class ProcessManager:
_instance = None
_processes: dict[int, subprocess.Popen] = {}
_lock: threading.Lock
_operation_locks: dict[int, threading.Lock] # per-server operation lock
@classmethod
def get() -> ProcessManager
def get_operation_lock(server_id) -> threading.Lock
# Returns a per-server lock that serializes start/stop/restart
# Prevents concurrent start+stop races for the same server
def start(server_id, exe_path, args: list[str], cwd: str) -> int # returns PID
def stop(server_id, timeout=30) -> bool
def kill(server_id) -> bool
@@ -579,6 +583,12 @@ class ConfigGenerator(Protocol):
def get_config_version(self) -> str:
"""Current adapter schema version. Stored in game_configs.schema_version."""
...
def migrate_config(self, old_version: str, config_json: dict[str, dict]) -> dict[str, dict]:
"""Transform config JSON from an older schema version to the current one.
Called by ConfigRepository when a section's stored schema_version
differs from get_config_version(). Returns the migrated config dict.
Raises ConfigMigrationError on failure (core rolls back; original stays)."""
...
def write_configs(self, server_id: int, server_dir: Path,
config_sections: dict[str, dict]) -> list[Path]: ...
def build_launch_args(self, config_sections: dict[str, dict],