102 lines
3.5 KiB
Python
102 lines
3.5 KiB
Python
from django.utils import timezone
|
|
from django.db import models
|
|
from ..models import AnalysisCache
|
|
import hashlib
|
|
import logging
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
class CacheService:
|
|
"""
|
|
Service for handling analysis result caching operations.
|
|
|
|
This service provides methods for generating cache keys, retrieving
|
|
cached results, and storing new results in the cache.
|
|
"""
|
|
|
|
def generate_hash(self, prompt, dealer_id, language):
|
|
"""
|
|
Generate a unique hash for the prompt, dealer, and language combination.
|
|
|
|
:param prompt: The user's prompt text
|
|
:type prompt: str
|
|
:param dealer_id: The dealer's ID
|
|
:type dealer_id: int
|
|
:param language: The language code
|
|
:type language: str
|
|
:return: MD5 hash string
|
|
:rtype: str
|
|
"""
|
|
cache_key = f"{prompt}:{dealer_id or 'all'}:{language}"
|
|
return hashlib.md5(cache_key.encode()).hexdigest()
|
|
|
|
def get_cached_result(self, prompt_hash, user, dealer_id):
|
|
"""
|
|
Retrieve a cached result if available and not expired.
|
|
|
|
:param prompt_hash: The hash key for the cache entry
|
|
:type prompt_hash: str
|
|
:param user: The user making the request
|
|
:type user: User
|
|
:param dealer_id: The dealer's ID
|
|
:type dealer_id: int
|
|
:return: Cached result or None if not found
|
|
:rtype: dict or None
|
|
"""
|
|
try:
|
|
cache_entry = AnalysisCache.objects.filter(
|
|
prompt_hash=prompt_hash,
|
|
dealer_id=dealer_id,
|
|
expires_at__gt=timezone.now()
|
|
).first()
|
|
|
|
# If user is authenticated, also check user-specific cache
|
|
if user and user.is_authenticated:
|
|
user_cache = AnalysisCache.objects.filter(
|
|
prompt_hash=prompt_hash,
|
|
user=user,
|
|
expires_at__gt=timezone.now()
|
|
).first()
|
|
|
|
# User-specific cache takes precedence
|
|
if user_cache:
|
|
return user_cache.result
|
|
|
|
return cache_entry.result if cache_entry else None
|
|
except Exception as e:
|
|
logger.warning(f"Error retrieving cache: {str(e)}")
|
|
return None
|
|
|
|
def cache_result(self, prompt_hash, result, user, dealer_id, duration=3600):
|
|
"""
|
|
Store a result in the cache.
|
|
|
|
:param prompt_hash: The hash key for the cache entry
|
|
:type prompt_hash: str
|
|
:param result: The result to cache
|
|
:type result: dict
|
|
:param user: The user making the request
|
|
:type user: User
|
|
:param dealer_id: The dealer's ID
|
|
:type dealer_id: int
|
|
:param duration: Cache duration in seconds
|
|
:type duration: int
|
|
:return: None
|
|
"""
|
|
try:
|
|
# Calculate expiration time
|
|
expires_at = timezone.now() + timezone.timedelta(seconds=duration)
|
|
|
|
# Create or update cache entry
|
|
AnalysisCache.objects.update_or_create(
|
|
prompt_hash=prompt_hash,
|
|
user=user if user and user.is_authenticated else None,
|
|
dealer_id=dealer_id,
|
|
defaults={
|
|
'result': result,
|
|
'expires_at': expires_at
|
|
}
|
|
)
|
|
except Exception as e:
|
|
logger.warning(f"Error caching result: {str(e)}")
|