166 lines
5.4 KiB
Python
166 lines
5.4 KiB
Python
"""Cache management API endpoints."""
|
|
|
|
from fastapi import APIRouter, Depends, HTTPException, Query
|
|
from typing import Dict, Any, Optional
|
|
|
|
from ..services.enhanced_cache_manager import EnhancedCacheManager, CacheConfig
|
|
from ..models.api_models import BaseResponse
|
|
|
|
router = APIRouter(prefix="/api/cache", tags=["cache"])
|
|
|
|
# Global instance of enhanced cache manager
|
|
_cache_manager_instance: Optional[EnhancedCacheManager] = None
|
|
|
|
|
|
async def get_enhanced_cache_manager() -> EnhancedCacheManager:
|
|
"""Get or create enhanced cache manager instance."""
|
|
global _cache_manager_instance
|
|
|
|
if not _cache_manager_instance:
|
|
config = CacheConfig(
|
|
redis_url="redis://localhost:6379/0", # TODO: Get from environment
|
|
transcript_ttl_hours=168, # 7 days
|
|
summary_ttl_hours=72, # 3 days
|
|
enable_analytics=True
|
|
)
|
|
_cache_manager_instance = EnhancedCacheManager(config)
|
|
await _cache_manager_instance.initialize()
|
|
|
|
return _cache_manager_instance
|
|
|
|
|
|
@router.get("/analytics", response_model=Dict[str, Any])
|
|
async def get_cache_analytics(
|
|
cache_manager: EnhancedCacheManager = Depends(get_enhanced_cache_manager)
|
|
) -> Dict[str, Any]:
|
|
"""Get comprehensive cache analytics and metrics.
|
|
|
|
Returns cache performance metrics, hit rates, memory usage, and configuration.
|
|
"""
|
|
try:
|
|
analytics = await cache_manager.get_cache_analytics()
|
|
|
|
return {
|
|
"status": "success",
|
|
"data": analytics
|
|
}
|
|
except Exception as e:
|
|
raise HTTPException(status_code=500, detail=f"Failed to get cache analytics: {str(e)}")
|
|
|
|
|
|
@router.post("/invalidate", response_model=Dict[str, Any])
|
|
async def invalidate_cache(
|
|
pattern: Optional[str] = Query(None, description="Optional pattern to match cache keys"),
|
|
cache_manager: EnhancedCacheManager = Depends(get_enhanced_cache_manager)
|
|
) -> Dict[str, Any]:
|
|
"""Invalidate cache entries.
|
|
|
|
Args:
|
|
pattern: Optional pattern to match cache keys. If not provided, clears all cache.
|
|
|
|
Returns:
|
|
Number of entries invalidated.
|
|
"""
|
|
try:
|
|
count = await cache_manager.invalidate_cache(pattern)
|
|
|
|
return {
|
|
"status": "success",
|
|
"message": f"Invalidated {count} cache entries",
|
|
"count": count
|
|
}
|
|
except Exception as e:
|
|
raise HTTPException(status_code=500, detail=f"Failed to invalidate cache: {str(e)}")
|
|
|
|
|
|
@router.get("/stats", response_model=Dict[str, Any])
|
|
async def get_cache_stats(
|
|
cache_manager: EnhancedCacheManager = Depends(get_enhanced_cache_manager)
|
|
) -> Dict[str, Any]:
|
|
"""Get basic cache statistics.
|
|
|
|
Returns cache hit rate, total operations, and error count.
|
|
"""
|
|
try:
|
|
metrics = cache_manager.metrics.to_dict()
|
|
|
|
return {
|
|
"status": "success",
|
|
"data": {
|
|
"hit_rate": metrics["hit_rate"],
|
|
"total_hits": metrics["hits"],
|
|
"total_misses": metrics["misses"],
|
|
"total_operations": metrics["total_operations"],
|
|
"average_response_time_ms": metrics["average_response_time_ms"],
|
|
"errors": metrics["errors"]
|
|
}
|
|
}
|
|
except Exception as e:
|
|
raise HTTPException(status_code=500, detail=f"Failed to get cache stats: {str(e)}")
|
|
|
|
|
|
@router.post("/warm", response_model=Dict[str, Any])
|
|
async def warm_cache(
|
|
video_ids: list[str],
|
|
cache_manager: EnhancedCacheManager = Depends(get_enhanced_cache_manager)
|
|
) -> Dict[str, Any]:
|
|
"""Warm cache for specific video IDs.
|
|
|
|
Args:
|
|
video_ids: List of YouTube video IDs to warm cache for.
|
|
|
|
Returns:
|
|
Status of cache warming operation.
|
|
"""
|
|
try:
|
|
# TODO: Implement cache warming logic
|
|
# This would fetch transcripts and generate summaries for the provided video IDs
|
|
|
|
return {
|
|
"status": "success",
|
|
"message": f"Cache warming initiated for {len(video_ids)} videos",
|
|
"video_count": len(video_ids)
|
|
}
|
|
except Exception as e:
|
|
raise HTTPException(status_code=500, detail=f"Failed to warm cache: {str(e)}")
|
|
|
|
|
|
@router.get("/health", response_model=Dict[str, Any])
|
|
async def cache_health_check(
|
|
cache_manager: EnhancedCacheManager = Depends(get_enhanced_cache_manager)
|
|
) -> Dict[str, Any]:
|
|
"""Check cache system health.
|
|
|
|
Returns health status of cache components.
|
|
"""
|
|
try:
|
|
health = {
|
|
"status": "healthy",
|
|
"components": {
|
|
"memory_cache": True,
|
|
"redis": False,
|
|
"background_tasks": cache_manager._initialized
|
|
}
|
|
}
|
|
|
|
# Check Redis connection
|
|
if cache_manager.redis_client:
|
|
try:
|
|
await cache_manager.redis_client.ping()
|
|
health["components"]["redis"] = True
|
|
except:
|
|
health["components"]["redis"] = False
|
|
|
|
# Check hit rate threshold
|
|
if cache_manager.metrics.hit_rate < cache_manager.config.hit_rate_alert_threshold:
|
|
health["warnings"] = [
|
|
f"Hit rate ({cache_manager.metrics.hit_rate:.2%}) below threshold ({cache_manager.config.hit_rate_alert_threshold:.2%})"
|
|
]
|
|
|
|
return health
|
|
|
|
except Exception as e:
|
|
return {
|
|
"status": "unhealthy",
|
|
"error": str(e)
|
|
} |