refactoring-backend #3
@@ -661,8 +661,8 @@ BanGUI maintains its **own SQLite database** (separate from the fail2ban databas
|
||||
- Session expiry is configurable (set during setup, stored in `settings`).
|
||||
- The frontend `AuthProvider` checks session validity on mount and redirects to `/login` if invalid.
|
||||
- The backend `dependencies.py` provides an `authenticated` dependency that validates the session cookie on every protected endpoint.
|
||||
- **Session validation cache** — validated session tokens are cached in memory for 10 seconds (`_session_cache` dict in `dependencies.py`) to avoid a SQLite round-trip on every request from the same browser. The cache is invalidated immediately on logout.
|
||||
This cache is process-local and not safe for multi-worker or distributed deployments. A clustered deployment should replace `_session_cache` with a shared cache or remove it entirely.
|
||||
- **Session validation cache** — validated session tokens are cached in memory for 10 seconds (`_session_cache` dict in `dependencies.py`) to avoid a SQLite round-trip on every request from the same browser. The cache is invalidated immediately on logout. This cache is process-local and not safe for multi-worker or distributed deployments. A clustered deployment should replace `_session_cache` with a shared cache or remove it entirely.
|
||||
- **Runtime state** — `RuntimeState` is process-local and only safe when BanGUI runs as a single asyncio worker. Mutating runtime state must not span `await` points because the current design relies on cooperative scheduling. Multi-worker or multi-process deployments must replace this runtime state with a shared coordination backend such as Redis, shared memory, or a database-backed store.
|
||||
- **Setup-completion flag** — once `is_setup_complete()` returns `True`, the result is stored in `app.state._setup_complete_cached`. The `SetupRedirectMiddleware` skips the DB query on all subsequent requests, removing 1 SQL query per request for the common post-setup case. The completion flag is only written after the runtime database is successfully initialized and all initial setup settings are persisted, preventing a failed setup from permanently bypassing the setup wizard.
|
||||
|
||||
---
|
||||
|
||||
@@ -98,6 +98,8 @@ Reference: `Docs/Refactoring.md` for full analysis of each issue.
|
||||
|
||||
**Why this is needed:** The safety of `RuntimeState` depends on an implicit assumption (single-worker, no `await` between read and write) that is not written down anywhere. If the deployment model changes or a developer modifies state-mutating functions, silent data races could appear with no warning. Explicit documentation prevents this.
|
||||
|
||||
**Status:** Completed.
|
||||
|
||||
---
|
||||
|
||||
### 6. `geo_service` Calls `db.commit()` Directly Instead of Deferring to Repository
|
||||
|
||||
@@ -5,6 +5,12 @@ exposed through a controlled state manager object. This keeps the FastAPI
|
||||
framework state bag limited to shared infrastructure handles and immutable
|
||||
configuration while still allowing existing code to access runtime values via
|
||||
attribute proxying.
|
||||
|
||||
RuntimeState is designed for a single-process, single-worker asyncio
|
||||
deployment. Mutations must complete without awaiting across read-modify-write
|
||||
sequences. If BanGUI is ever deployed with multiple workers or across processes,
|
||||
this module must be replaced with a shared backend such as Redis or shared
|
||||
memory.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
@@ -13,9 +19,8 @@ import datetime
|
||||
from dataclasses import dataclass, field
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from starlette.datastructures import State
|
||||
|
||||
import structlog
|
||||
from starlette.datastructures import State
|
||||
|
||||
from app.models.config import PendingRecovery
|
||||
from app.models.server import ServerStatus
|
||||
|
||||
Reference in New Issue
Block a user