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,
)
from paskia.db.bootstrap import bootstrap
from paskia.db.lifecycle import cleanup_expired, init
from paskia.db.operations import (
add_permission_to_org,
add_permission_to_role,
cleanup_expired,
create_credential,
create_credential_session,
create_org,
@@ -52,7 +52,6 @@ from paskia.db.operations import (
get_reset_token,
get_user_credential_ids,
get_user_organization,
init,
login,
remove_permission_from_org,
remove_permission_from_role,
+5 -4
View File
@@ -8,7 +8,8 @@ import asyncio
import logging
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
CLEANUP_INTERVAL = 1 # Expired item cleanup
@@ -20,11 +21,11 @@ _background_task: asyncio.Task | None = None
async def flush() -> None:
"""Write all pending database changes to disk."""
if _store is None:
store = _ops._store
if store is None:
_logger.warning("flush() called but _store is None")
return
await _store.flush()
await store.flush()
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 logging
import os
from datetime import UTC, datetime, timedelta
from uuid import UUID
@@ -41,19 +40,6 @@ _db._store = _store
_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
# -------------------------------------------------------------------------
@@ -555,27 +541,6 @@ def delete_reset_token(key: bytes, *, ctx: SessionContext | None = None) -> None
_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)
# -------------------------------------------------------------------------