feat(team): invalidate team ranking cache when team members changed

This commit is contained in:
MingxuanGame
2025-08-30 11:56:36 +00:00
parent e872c25918
commit 76f38b84b9
2 changed files with 34 additions and 1 deletions

View File

@@ -4,7 +4,7 @@ import hashlib
from app.database.lazer_user import BASE_INCLUDES, User, UserResp from app.database.lazer_user import BASE_INCLUDES, User, UserResp
from app.database.team import Team, TeamMember, TeamRequest from app.database.team import Team, TeamMember, TeamRequest
from app.dependencies.database import Database from app.dependencies.database import Database, get_redis
from app.dependencies.storage import get_storage_service from app.dependencies.storage import get_storage_service
from app.dependencies.user import get_client_user from app.dependencies.user import get_client_user
from app.models.notification import ( from app.models.notification import (
@@ -13,6 +13,7 @@ from app.models.notification import (
TeamApplicationStore, TeamApplicationStore,
) )
from app.router.notification import server from app.router.notification import server
from app.service.ranking_cache_service import get_ranking_cache_service
from app.storage.base import StorageService from app.storage.base import StorageService
from app.utils import check_image, utcnow from app.utils import check_image, utcnow
@@ -20,6 +21,7 @@ from .router import router
from fastapi import Depends, File, Form, HTTPException, Path, Request, Security from fastapi import Depends, File, Form, HTTPException, Path, Request, Security
from pydantic import BaseModel from pydantic import BaseModel
from redis.asyncio import Redis
from sqlmodel import exists, select from sqlmodel import exists, select
@@ -32,6 +34,7 @@ async def create_team(
cover: bytes = File(..., description="战队头图文件"), cover: bytes = File(..., description="战队头图文件"),
name: str = Form(max_length=100, description="战队名称"), name: str = Form(max_length=100, description="战队名称"),
short_name: str = Form(max_length=10, description="战队缩写"), short_name: str = Form(max_length=10, description="战队缩写"),
redis: Redis = Depends(get_redis),
): ):
"""创建战队。 """创建战队。
@@ -75,6 +78,9 @@ async def create_team(
await session.commit() await session.commit()
await session.refresh(team) await session.refresh(team)
cache_service = get_ranking_cache_service(redis)
await cache_service.invalidate_team_cache()
return team return team
@@ -157,6 +163,7 @@ async def delete_team(
session: Database, session: Database,
team_id: int = Path(..., description="战队 ID"), team_id: int = Path(..., description="战队 ID"),
current_user: User = Security(get_client_user), current_user: User = Security(get_client_user),
redis: Redis = Depends(get_redis),
): ):
team = await session.get(Team, team_id) team = await session.get(Team, team_id)
if not team: if not team:
@@ -172,6 +179,9 @@ async def delete_team(
await session.delete(team) await session.delete(team)
await session.commit() await session.commit()
cache_service = get_ranking_cache_service(redis)
await cache_service.invalidate_team_cache()
class TeamQueryResp(BaseModel): class TeamQueryResp(BaseModel):
team: Team team: Team
@@ -224,6 +234,7 @@ async def handle_request(
team_id: int = Path(..., description="战队 ID"), team_id: int = Path(..., description="战队 ID"),
user_id: int = Path(..., description="用户 ID"), user_id: int = Path(..., description="用户 ID"),
current_user: User = Security(get_client_user), current_user: User = Security(get_client_user),
redis: Redis = Depends(get_redis),
): ):
team = await session.get(Team, team_id) team = await session.get(Team, team_id)
if not team: if not team:
@@ -249,6 +260,9 @@ async def handle_request(
session.add(TeamMember(user_id=user_id, team_id=team_id, joined_at=utcnow())) session.add(TeamMember(user_id=user_id, team_id=team_id, joined_at=utcnow()))
await server.new_private_notification(TeamApplicationAccept.init(team_request)) await server.new_private_notification(TeamApplicationAccept.init(team_request))
cache_service = get_ranking_cache_service(redis)
await cache_service.invalidate_team_cache()
else: else:
await server.new_private_notification(TeamApplicationReject.init(team_request)) await server.new_private_notification(TeamApplicationReject.init(team_request))
await session.delete(team_request) await session.delete(team_request)
@@ -261,6 +275,7 @@ async def kick_member(
team_id: int = Path(..., description="战队 ID"), team_id: int = Path(..., description="战队 ID"),
user_id: int = Path(..., description="用户 ID"), user_id: int = Path(..., description="用户 ID"),
current_user: User = Security(get_client_user), current_user: User = Security(get_client_user),
redis: Redis = Depends(get_redis),
): ):
team = await session.get(Team, team_id) team = await session.get(Team, team_id)
if not team: if not team:
@@ -280,3 +295,6 @@ async def kick_member(
await session.delete(team_member) await session.delete(team_member)
await session.commit() await session.commit()
cache_service = get_ranking_cache_service(redis)
await cache_service.invalidate_team_cache()

View File

@@ -604,6 +604,21 @@ class RankingCacheService:
except Exception as e: except Exception as e:
logger.error(f"Error invalidating country cache: {e}") logger.error(f"Error invalidating country cache: {e}")
async def invalidate_team_cache(self, ruleset: GameMode | None = None) -> None:
"""使战队排行榜缓存失效"""
try:
if ruleset:
pattern = f"team_ranking:{ruleset}:*"
else:
pattern = "team_ranking:*"
keys = await self.redis.keys(pattern)
if keys:
await self.redis.delete(*keys)
logger.info(f"Invalidated {len(keys)} team ranking cache keys")
except Exception as e:
logger.error(f"Error invalidating team cache: {e}")
async def get_cache_stats(self) -> dict: async def get_cache_stats(self) -> dict:
"""获取缓存统计信息""" """获取缓存统计信息"""
try: try: