Refactor DB lifecycle functions init and cleanup to separate db.lifecycle module.
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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():
|
||||
|
||||
@@ -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
|
||||
@@ -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)
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user