Add in-memory read cache with CUD-based invalidation

This commit is contained in:
Chris
2026-04-03 02:32:38 +08:00
parent e912d1498e
commit 55e640f2fb
6 changed files with 194 additions and 20 deletions

View File

@@ -9,6 +9,7 @@ from app.schemas.auth import ProviderPrincipal, MeSummaryResponse
from app.schemas.permissions import RoleSnapshotResponse
from app.security.idp_jwt import require_authenticated_principal
from app.services.permission_service import PermissionService
from app.services.runtime_cache import runtime_cache
router = APIRouter(prefix="/me", tags=["me"])
@@ -18,6 +19,10 @@ def get_me(
principal: ProviderPrincipal = Depends(require_authenticated_principal),
db: Session = Depends(get_db),
) -> MeSummaryResponse:
cache_key = f"me:{principal.sub}"
cached = runtime_cache.get(cache_key)
if isinstance(cached, MeSummaryResponse):
return cached
try:
users_repo = UsersRepository(db)
user = users_repo.upsert_by_sub(
@@ -28,13 +33,17 @@ def get_me(
is_active=True,
status="active",
)
return MeSummaryResponse(sub=user.user_sub, email=user.email, display_name=user.display_name)
result = MeSummaryResponse(sub=user.user_sub, email=user.email, display_name=user.display_name)
runtime_cache.set(cache_key, result, ttl_seconds=30)
return result
except SQLAlchemyError:
return MeSummaryResponse(
result = MeSummaryResponse(
sub=principal.sub,
email=principal.email,
display_name=principal.name or principal.preferred_username,
)
runtime_cache.set(cache_key, result, ttl_seconds=15)
return result
@router.get("/permissions/snapshot", response_model=RoleSnapshotResponse)
@@ -42,6 +51,10 @@ def get_my_permission_snapshot(
principal: ProviderPrincipal = Depends(require_authenticated_principal),
db: Session = Depends(get_db),
) -> RoleSnapshotResponse:
cache_key = f"me:permissions_snapshot:{principal.sub}"
cached = runtime_cache.get(cache_key)
if isinstance(cached, RoleSnapshotResponse):
return cached
try:
users_repo = UsersRepository(db)
user_sites_repo = UserSitesRepository(db)
@@ -68,6 +81,10 @@ def get_my_permission_snapshot(
)
for site, company, role, system in rows
]
return PermissionService.build_role_snapshot(user_sub=principal.sub, rows=serialized)
result = PermissionService.build_role_snapshot(user_sub=principal.sub, rows=serialized)
runtime_cache.set(cache_key, result, ttl_seconds=30)
return result
except SQLAlchemyError:
return RoleSnapshotResponse(user_sub=principal.sub, roles=[])
result = RoleSnapshotResponse(user_sub=principal.sub, roles=[])
runtime_cache.set(cache_key, result, ttl_seconds=10)
return result