refactor(usage): address round-2 review on PR #871
- remove accidentally-committed .claude/scheduled_tasks.lock (Claude Code runtime artifact swept in by `git add -A`) and gitignore it; the rest of .claude/ stays tracked. - store: cache UsageEventStore.shared() as a process-wide instance so the hot search path doesn't allocate a fresh wrapper per metered query (the wrapper is stateless beyond its storage handle). - hooks: pass enabled=True directly (the outer guard already confirmed the flag) instead of re-reading settings.usage_metering_enabled. - migration: document the no-TTL retention design (control-plane rollup owns the lifecycle; the data plane only appends). - tests: assert the best-effort error path logs at WARNING (observability contract). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
702f66e6b1
commit
2bbf4ed967
@@ -51,18 +51,27 @@ _INSERT_SQL = (
|
||||
class UsageEventStore:
|
||||
"""Append-only writer for the app-DB ``usage_events`` table."""
|
||||
|
||||
# Process-wide cached instance returned by ``shared()`` so the hot search
|
||||
# path doesn't allocate a fresh wrapper per metered query. The store is
|
||||
# stateless beyond its storage handle, so one instance is reusable.
|
||||
_shared_instance: "UsageEventStore | None" = None
|
||||
|
||||
def __init__(self, storage: RefreshTokenStorage) -> None:
|
||||
self._storage = storage
|
||||
|
||||
@classmethod
|
||||
async def shared(cls) -> "UsageEventStore":
|
||||
"""Build a store backed by the process-wide storage singleton.
|
||||
"""Return the process-wide store backed by the storage singleton.
|
||||
|
||||
``get_shared_storage()`` runs ``initialize()`` (and thus Alembic
|
||||
migrations) on first access, so the ``usage_events`` table is present
|
||||
by the time any event is recorded.
|
||||
Cached after first build: ``get_shared_storage()`` already returns the
|
||||
cached :class:`RefreshTokenStorage` (running ``initialize()`` / Alembic
|
||||
on first access, so ``usage_events`` exists), and the wrapper itself is
|
||||
stateless, so reusing one instance avoids a per-call allocation on the
|
||||
``nc_semantic_search`` hot path.
|
||||
"""
|
||||
return cls(await get_shared_storage())
|
||||
if cls._shared_instance is None:
|
||||
cls._shared_instance = cls(await get_shared_storage())
|
||||
return cls._shared_instance
|
||||
|
||||
async def record_usage_event(
|
||||
self,
|
||||
|
||||
Reference in New Issue
Block a user