Debug JSONL updates.
This commit is contained in:
+4
-13
@@ -47,23 +47,16 @@ def cleanup() -> None:
|
||||
|
||||
async def flush() -> None:
|
||||
"""Write all pending database changes to disk."""
|
||||
import sys
|
||||
from paskia.db.operations import _db
|
||||
|
||||
if _db is None:
|
||||
_logger.warning("flush() called but _db is None")
|
||||
print("[DB] flush() called but _db is None", file=sys.stderr)
|
||||
return
|
||||
pending_count = len(_db._pending_changes)
|
||||
if pending_count > 0:
|
||||
print(f"[DB] flush() called with {pending_count} pending changes, db_path={_db.db_path}", file=sys.stderr)
|
||||
await flush_changes(_db.db_path, _db._pending_changes)
|
||||
|
||||
|
||||
async def _background_loop():
|
||||
"""Background task that periodically flushes changes and cleans up."""
|
||||
import sys
|
||||
print("[DB] Background loop starting", file=sys.stderr)
|
||||
_logger.info("Background loop starting")
|
||||
# Run cleanup immediately on startup to clear old expired items
|
||||
cleanup()
|
||||
@@ -94,13 +87,12 @@ async def _background_loop():
|
||||
|
||||
async def start_background():
|
||||
"""Start the background flush/cleanup task."""
|
||||
import sys
|
||||
global _background_task
|
||||
|
||||
# Check if task exists but is no longer running (e.g., after uvicorn reload)
|
||||
if _background_task is not None:
|
||||
if _background_task.done():
|
||||
print(f"[DB] Previous background task was done, restarting", file=sys.stderr)
|
||||
_logger.debug("Previous background task was done, restarting")
|
||||
_background_task = None
|
||||
else:
|
||||
# Task exists and is running - but might be in a dead event loop
|
||||
@@ -109,18 +101,17 @@ async def start_background():
|
||||
loop = asyncio.get_running_loop()
|
||||
task_loop = _background_task.get_loop()
|
||||
if loop is not task_loop:
|
||||
print(f"[DB] Background task in different event loop, restarting", file=sys.stderr)
|
||||
_logger.debug("Background task in different event loop, restarting")
|
||||
_background_task = None
|
||||
except Exception as e:
|
||||
print(f"[DB] Error checking background task loop: {e}, restarting", file=sys.stderr)
|
||||
_logger.debug("Error checking background task loop: %s, restarting", e)
|
||||
_background_task = None
|
||||
|
||||
if _background_task is None:
|
||||
_background_task = asyncio.create_task(_background_loop())
|
||||
_logger.info("Database background task started")
|
||||
print("[DB] Database background task started", file=sys.stderr)
|
||||
else:
|
||||
print(f"[DB] Background task already running: {_background_task}", file=sys.stderr)
|
||||
_logger.debug("Background task already running: %s", _background_task)
|
||||
|
||||
|
||||
async def stop_background():
|
||||
|
||||
+1
-3
@@ -119,11 +119,9 @@ async def flush_changes(
|
||||
# Append all lines in a single write (binary mode for Windows compatibility)
|
||||
async with aiofiles.open(db_path, "ab") as f:
|
||||
await f.write(b"\n".join(lines) + b"\n")
|
||||
_logger.info(
|
||||
_logger.debug(
|
||||
"Flushed %d change(s) to %s", len(changes_to_write), db_path
|
||||
)
|
||||
import sys
|
||||
print(f"[DB] Flushed {len(changes_to_write)} change(s) to {db_path}", file=sys.stderr)
|
||||
return True
|
||||
except OSError:
|
||||
_logger.exception("Failed to flush database changes")
|
||||
|
||||
+11
-24
@@ -101,15 +101,17 @@ class DB:
|
||||
create_change_record(self._current_actor, diff)
|
||||
)
|
||||
self._previous_builtins = current
|
||||
_logger.info(
|
||||
"Queued change by %s, %d pending",
|
||||
self._current_actor,
|
||||
len(self._pending_changes),
|
||||
)
|
||||
import sys
|
||||
# Log the change with user display name if available
|
||||
actor_display = self._current_actor
|
||||
if self._current_actor not in ("system", "expiry", "migrate"):
|
||||
try:
|
||||
user_uuid = UUID(self._current_actor)
|
||||
if user_uuid in self._data.users:
|
||||
actor_display = self._data.users[user_uuid].display_name
|
||||
except (ValueError, KeyError):
|
||||
pass
|
||||
import json
|
||||
print(f"[DB] Queued change by {self._current_actor}, {len(self._pending_changes)} pending", file=sys.stderr)
|
||||
print(f"[DB] diff: {json.dumps(diff, default=str)}", file=sys.stderr)
|
||||
_logger.info("DB change by %s: %s", actor_display, json.dumps(diff, default=str))
|
||||
|
||||
@contextmanager
|
||||
def transaction(self, actor: str = "system"):
|
||||
@@ -173,10 +175,8 @@ def build_role(uuid: UUID) -> Role:
|
||||
|
||||
|
||||
def build_org(uuid: UUID, include_roles: bool = False) -> Org:
|
||||
import sys
|
||||
o = _db._data.orgs[uuid]
|
||||
perm_scopes = [p.scope for p in _db._data.permissions.values() if uuid in p.orgs]
|
||||
print(f"[DB] build_org({uuid}): permissions={perm_scopes}", file=sys.stderr)
|
||||
org = Org(uuid=uuid, display_name=o.display_name, permissions=perm_scopes)
|
||||
if include_roles:
|
||||
org.roles = [
|
||||
@@ -528,9 +528,8 @@ def rename_permission(
|
||||
"""Rename a permission's scope. The UUID remains the same.
|
||||
|
||||
Also updates all role references to use the new scope.
|
||||
Note: Scopes do not need to be unique (same scope with different domains is valid).
|
||||
"""
|
||||
import sys
|
||||
|
||||
# Find permission by old scope
|
||||
key = None
|
||||
for pid, p in _db._data.permissions.items():
|
||||
@@ -540,15 +539,6 @@ def rename_permission(
|
||||
if not key:
|
||||
raise ValueError(f"Permission with scope '{old_scope}' not found")
|
||||
|
||||
# Check if new scope already exists (on a different permission)
|
||||
for pid, p in _db._data.permissions.items():
|
||||
if p.scope == new_scope and pid != key:
|
||||
raise ValueError(f"Permission with scope '{new_scope}' already exists")
|
||||
|
||||
# Debug: Print orgs before change
|
||||
print(f"[DB] rename_permission: {old_scope} -> {new_scope}", file=sys.stderr)
|
||||
print(f"[DB] orgs BEFORE: {_db._data.permissions[key].orgs}", file=sys.stderr)
|
||||
|
||||
with _db.transaction(actor):
|
||||
# Update the permission
|
||||
_db._data.permissions[key].scope = new_scope
|
||||
@@ -562,9 +552,6 @@ def rename_permission(
|
||||
del r.permissions[old_scope]
|
||||
r.permissions[new_scope] = True
|
||||
|
||||
# Debug: Print orgs after change
|
||||
print(f"[DB] orgs AFTER: {_db._data.permissions[key].orgs}", file=sys.stderr)
|
||||
|
||||
|
||||
def delete_permission(uuid: str | UUID, actor: str = "system") -> None:
|
||||
"""Delete a permission."""
|
||||
|
||||
Reference in New Issue
Block a user