CLAUDE: Add Redis cache invalidation to player mutation endpoints
- Add cache invalidation to PUT, PATCH, POST, and DELETE endpoints
- Invalidate all player list, search, and detail caches on data changes
- Increase cache TTLs now that invalidation ensures accuracy:
- GET /players: 10min → 30min
- GET /players/search: 5min → 15min
- GET /players/{player_id}: 10min → 30min
This ensures users see updated player data immediately after changes
while benefiting from longer cache lifetimes for read operations.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
a9e749640d
commit
4db6982bc5
@ -5,7 +5,7 @@ import pydantic
|
||||
from pandas import DataFrame
|
||||
|
||||
from ..db_engine import db, Player, model_to_dict, chunked, fn, complex_data_to_csv
|
||||
from ..dependencies import add_cache_headers, cache_result, oauth2_scheme, valid_token, PRIVATE_IN_SCHEMA, handle_db_errors
|
||||
from ..dependencies import add_cache_headers, cache_result, oauth2_scheme, valid_token, PRIVATE_IN_SCHEMA, handle_db_errors, invalidate_cache
|
||||
|
||||
logger = logging.getLogger('discord_app')
|
||||
|
||||
@ -49,7 +49,7 @@ class PlayerList(pydantic.BaseModel):
|
||||
|
||||
@router.get('')
|
||||
@handle_db_errors
|
||||
@add_cache_headers(max_age=10*60)
|
||||
@add_cache_headers(max_age=30*60) # 30 minutes - safe with cache invalidation on writes
|
||||
async def get_players(
|
||||
season: Optional[int], name: Optional[str] = None, team_id: list = Query(default=None),
|
||||
pos: list = Query(default=None), strat_code: list = Query(default=None), is_injured: Optional[bool] = None,
|
||||
@ -126,7 +126,7 @@ async def get_players(
|
||||
|
||||
@router.get('/search')
|
||||
@handle_db_errors
|
||||
@add_cache_headers(max_age=5*60)
|
||||
@add_cache_headers(max_age=15*60) # 15 minutes - safe with cache invalidation on writes
|
||||
async def search_players(
|
||||
q: str = Query(..., description="Search query for player name"),
|
||||
season: Optional[int] = Query(default=None, description="Season to search in (defaults to current)"),
|
||||
@ -177,7 +177,7 @@ async def search_players(
|
||||
|
||||
@router.get('/{player_id}')
|
||||
@handle_db_errors
|
||||
@add_cache_headers(max_age=10*60)
|
||||
@add_cache_headers(max_age=30*60) # 30 minutes - safe with cache invalidation on writes
|
||||
async def get_one_player(player_id: int, short_output: Optional[bool] = False):
|
||||
this_player = Player.get_or_none(Player.id == player_id)
|
||||
if this_player:
|
||||
@ -203,6 +203,12 @@ async def put_player(
|
||||
Player.update(**new_player.dict()).where(Player.id == player_id).execute()
|
||||
r_player = model_to_dict(Player.get_by_id(player_id))
|
||||
db.close()
|
||||
|
||||
# Invalidate player-related cache entries
|
||||
invalidate_cache("api:get_players*")
|
||||
invalidate_cache("api:search_players*")
|
||||
invalidate_cache(f"api:get_one_player*{player_id}*")
|
||||
|
||||
return r_player
|
||||
|
||||
|
||||
@ -268,7 +274,7 @@ async def patch_player(
|
||||
this_player.headshot = headshot
|
||||
|
||||
if il_return is not None:
|
||||
this_player.il_return = None if il_return == '' else il_return
|
||||
this_player.il_return = None if not il_return or il_return.lower() == 'none' else il_return
|
||||
if demotion_week is not None:
|
||||
this_player.demotion_week = demotion_week
|
||||
if strat_code is not None:
|
||||
@ -283,6 +289,12 @@ async def patch_player(
|
||||
if this_player.save() == 1:
|
||||
r_player = model_to_dict(this_player)
|
||||
db.close()
|
||||
|
||||
# Invalidate player-related cache entries
|
||||
invalidate_cache("api:get_players*")
|
||||
invalidate_cache("api:search_players*")
|
||||
invalidate_cache(f"api:get_one_player*{player_id}*")
|
||||
|
||||
return r_player
|
||||
else:
|
||||
db.close()
|
||||
@ -313,6 +325,11 @@ async def post_players(p_list: PlayerList, token: str = Depends(oauth2_scheme)):
|
||||
Player.insert_many(batch).on_conflict_ignore().execute()
|
||||
db.close()
|
||||
|
||||
# Invalidate player-related cache entries
|
||||
invalidate_cache("api:get_players*")
|
||||
invalidate_cache("api:search_players*")
|
||||
invalidate_cache("api:get_one_player*")
|
||||
|
||||
return f'Inserted {len(new_players)} players'
|
||||
|
||||
|
||||
@ -332,6 +349,11 @@ async def delete_player(player_id: int, token: str = Depends(oauth2_scheme)):
|
||||
db.close()
|
||||
|
||||
if count == 1:
|
||||
# Invalidate player-related cache entries
|
||||
invalidate_cache("api:get_players*")
|
||||
invalidate_cache("api:search_players*")
|
||||
invalidate_cache(f"api:get_one_player*{player_id}*")
|
||||
|
||||
return f'Player {player_id} has been deleted'
|
||||
else:
|
||||
raise HTTPException(status_code=500, detail=f'Player {player_id} could not be deleted')
|
||||
|
||||
Loading…
Reference in New Issue
Block a user