haikal/haikalbot/services/cache_service.py
Marwan Alwali 250e0aa7bb update
2025-05-26 15:17:10 +03:00

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)}")