Refactor DB lifecycle functions init and cleanup to separate db.lifecycle module.

This commit is contained in:
2026-02-10 22:28:38 +00:00
parent b0b36e88b1
commit 1cfde06de9
4 changed files with 45 additions and 41 deletions
+1 -2
View File
@@ -27,10 +27,10 @@ from paskia.db.background import (
stop_cleanup, stop_cleanup,
) )
from paskia.db.bootstrap import bootstrap from paskia.db.bootstrap import bootstrap
from paskia.db.lifecycle import cleanup_expired, init
from paskia.db.operations import ( from paskia.db.operations import (
add_permission_to_org, add_permission_to_org,
add_permission_to_role, add_permission_to_role,
cleanup_expired,
create_credential, create_credential,
create_credential_session, create_credential_session,
create_org, create_org,
@@ -52,7 +52,6 @@ from paskia.db.operations import (
get_reset_token, get_reset_token,
get_user_credential_ids, get_user_credential_ids,
get_user_organization, get_user_organization,
init,
login, login,
remove_permission_from_org, remove_permission_from_org,
remove_permission_from_role, remove_permission_from_role,
+5 -4
View File
@@ -8,7 +8,8 @@ import asyncio
import logging import logging
from datetime import UTC, datetime from datetime import UTC, datetime
from paskia.db.operations import _store, cleanup_expired import paskia.db.operations as _ops
from paskia.db.lifecycle import cleanup_expired
FLUSH_INTERVAL = 0.1 # Flush to disk FLUSH_INTERVAL = 0.1 # Flush to disk
CLEANUP_INTERVAL = 1 # Expired item cleanup CLEANUP_INTERVAL = 1 # Expired item cleanup
@@ -20,11 +21,11 @@ _background_task: asyncio.Task | None = None
async def flush() -> None: async def flush() -> None:
"""Write all pending database changes to disk.""" """Write all pending database changes to disk."""
store = _ops._store
if _store is None: if store is None:
_logger.warning("flush() called but _store is None") _logger.warning("flush() called but _store is None")
return return
await _store.flush() await store.flush()
async def _background_loop(): async def _background_loop():
+39
View File
@@ -0,0 +1,39 @@
"""
Database lifecycle: initialization and maintenance.
"""
import logging
import os
from datetime import UTC, datetime
import paskia.db.operations as _ops
_logger = logging.getLogger(__name__)
async def init(rp_id: str = "localhost", *args, **kwargs):
"""Load database from JSONL file."""
if _ops._initialized:
_logger.debug("Database already initialized, skipping reload")
return
default_path = f"{rp_id}.paskiadb"
db_path = os.environ.get("PASKIA_DB", default_path)
await _ops._store.load(db_path, rp_id=rp_id)
_ops._db = _ops._store.db
_ops._initialized = True
def cleanup_expired() -> int:
"""Remove expired sessions and reset tokens. Returns count removed."""
now = datetime.now(UTC)
count = 0
with _ops._db.transaction("expiry"):
expired_sessions = [k for k, s in _ops._db.sessions.items() if s.expiry < now]
for k in expired_sessions:
del _ops._db.sessions[k]
count += 1
expired_tokens = [k for k, t in _ops._db.reset_tokens.items() if t.expiry < now]
for k in expired_tokens:
del _ops._db.reset_tokens[k]
count += 1
return count
-35
View File
@@ -8,7 +8,6 @@ Write operations: Functions that validate and commit, or raise ValueError.
import hashlib import hashlib
import logging import logging
import os
from datetime import UTC, datetime, timedelta from datetime import UTC, datetime, timedelta
from uuid import UUID from uuid import UUID
@@ -41,19 +40,6 @@ _db._store = _store
_initialized = False _initialized = False
async def init(rp_id: str = "localhost", *args, **kwargs):
"""Load database from JSONL file."""
global _db, _initialized
if _initialized:
_logger.debug("Database already initialized, skipping reload")
return
default_path = f"{rp_id}.paskiadb"
db_path = os.environ.get("PASKIA_DB", default_path)
await _store.load(db_path, rp_id=rp_id)
_db = _store.db
_initialized = True
# ------------------------------------------------------------------------- # -------------------------------------------------------------------------
# Read/lookup functions # Read/lookup functions
# ------------------------------------------------------------------------- # -------------------------------------------------------------------------
@@ -555,27 +541,6 @@ def delete_reset_token(key: bytes, *, ctx: SessionContext | None = None) -> None
_db.reset_tokens[key].delete() _db.reset_tokens[key].delete()
# -------------------------------------------------------------------------
# Cleanup (called by background task)
# -------------------------------------------------------------------------
def cleanup_expired() -> int:
"""Remove expired sessions and reset tokens. Returns count removed."""
now = datetime.now(UTC)
count = 0
with _db.transaction("expiry"):
expired_sessions = [k for k, s in _db.sessions.items() if s.expiry < now]
for k in expired_sessions:
del _db.sessions[k]
count += 1
expired_tokens = [k for k, t in _db.reset_tokens.items() if t.expiry < now]
for k in expired_tokens:
del _db.reset_tokens[k]
count += 1
return count
# ------------------------------------------------------------------------- # -------------------------------------------------------------------------
# Composite operations (used by app code) # Composite operations (used by app code)
# ------------------------------------------------------------------------- # -------------------------------------------------------------------------