feat(team): invalidate team ranking cache when team members changed
This commit is contained in:
@@ -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()
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
Reference in New Issue
Block a user