Quality cleanup refactoring

Made-with: Cursor
This commit is contained in:
Oleksandr Bezdieniezhnykh
2026-04-13 06:21:26 +03:00
parent 8f7deb3fca
commit 4eaf218f09
33 changed files with 957 additions and 207 deletions
+21 -14
View File
@@ -33,29 +33,36 @@ FastAPI application entry point providing HTTP endpoints for health checks, auth
### Module-level State
| Name | Type | Description |
|----------------|--------------------|------------------------------------------------|
| api_client | ApiClient or None | Lazy-initialized singleton |
| unlock_state | UnlockState | Current unlock workflow state |
| unlock_error | Optional[str] | Last unlock error message |
| unlock_lock | threading.Lock | Thread safety for unlock state mutations |
| Name | Type | Description |
|-------------------|-------------------------|----------------------------------------------------------------|
| `_api_client` | `ApiClient` or `None` | Lazy-initialized singleton |
| `_api_client_lock`| `threading.Lock` | Protects lazy initialization of `_api_client` (double-checked) |
| `_unlock` | `_UnlockStateHolder` | Holds unlock workflow state and last error under an inner lock |
#### `_UnlockStateHolder`
| Member | Description |
|-----------|-----------------------------------------------------------------------------|
| `get()` | Returns `(state: UnlockState, error: Optional[str])` under lock |
| `set(state, error=None)` | Sets state and optional error message under lock |
| `state` (property) | Current `UnlockState` (read under lock) |
## Internal Logic
### `get_api_client()`
Lazy singleton pattern: creates `ApiClient(RESOURCE_API_URL)` on first call.
Double-checked locking: if `_api_client` is `None`, acquires `_api_client_lock`, re-checks, then imports `ApiClient` and constructs `ApiClient(RESOURCE_API_URL)` once.
### Unlock Workflow (`_run_unlock`)
Background task (via FastAPI BackgroundTasks) that runs these steps:
1. Check if Docker images already loaded → if yes, set `ready`
1. Check if Docker images already loaded → if yes, set `ready` (preserving any prior error from `get()`)
2. Authenticate with API (login)
3. Download key fragment from `/binary-split/key-fragment`
4. Decrypt archive at `IMAGES_PATH``.tar`
5. `docker load` the tar file
6. Clean up tar file
7. Set state to `ready` (or `error` on failure)
6. Remove tar file; on `OSError`, log a warning and continue
7. Set state to `ready` with no error (or `error` on failure)
State transitions are guarded by `unlock_lock` (threading.Lock).
State and error are updated only through `_unlock.set()` and read via `_unlock.get()` / `_unlock.state`.
### `/unlock` Endpoint
- If already `ready` → return immediately
@@ -65,8 +72,8 @@ State transitions are guarded by `unlock_lock` (threading.Lock).
## Dependencies
- **Internal**: `unlock_state` (UnlockState enum), `api_client` (lazy import), `binary_split` (lazy import)
- **External**: `os`, `threading` (stdlib), `fastapi`, `pydantic`
- **Internal**: `UnlockState` from `unlock_state`, `get_api_client()` (lazy `api_client` import), `binary_split` (lazy import in unlock paths)
- **External**: `os`, `threading` (stdlib), `fastapi`, `pydantic`, `loguru` (logger for tar cleanup warnings)
## Consumers
@@ -94,7 +101,7 @@ None — this is the entry point module.
- Login endpoint returns 401 on auth failure
- All resource endpoints use authenticated API client
- Unlock state is thread-safe via `threading.Lock`
- Unlock state and error are guarded by `_UnlockStateHolder`s lock; API client initialization is guarded by `_api_client_lock`
- Lazy imports of Cython modules (`api_client`, `binary_split`) to avoid import-time side effects
## Tests