"""Redis 서비스 - 실시간 텍스트 축적""" import redis.asyncio as redis import logging from typing import List from app.config import get_settings logger = logging.getLogger(__name__) settings = get_settings() class RedisService: """Redis 서비스 (슬라이딩 윈도우 방식)""" def __init__(self): self.redis_client = None async def connect(self): """Redis 연결""" try: self.redis_client = await redis.Redis( host=settings.redis_host, port=settings.redis_port, password=settings.redis_password, db=settings.redis_db, decode_responses=True ) await self.redis_client.ping() logger.info("Redis 연결 성공") except Exception as e: logger.error(f"Redis 연결 실패: {e}") raise async def disconnect(self): """Redis 연결 종료""" if self.redis_client: await self.redis_client.close() logger.info("Redis 연결 종료") async def add_transcript_segment( self, meeting_id: str, text: str, timestamp: int ): """ 실시간 텍스트 세그먼트 추가 (슬라이딩 윈도우) Args: meeting_id: 회의 ID text: 텍스트 세그먼트 timestamp: 타임스탬프 (밀리초) """ key = f"meeting:{meeting_id}:transcript" value = f"{timestamp}:{text}" # Sorted Set에 추가 (타임스탬프를 스코어로) await self.redis_client.zadd(key, {value: timestamp}) # 설정된 시간 이전 데이터 제거 (기본 5분) retention_ms = settings.text_retention_seconds * 1000 cutoff_time = timestamp - retention_ms await self.redis_client.zremrangebyscore(key, 0, cutoff_time) logger.debug(f"텍스트 세그먼트 추가 - meetingId: {meeting_id}") async def get_accumulated_text(self, meeting_id: str) -> str: """ 누적된 텍스트 조회 (최근 5분) Args: meeting_id: 회의 ID Returns: 누적된 텍스트 (시간순) """ key = f"meeting:{meeting_id}:transcript" # 최신순으로 모든 세그먼트 조회 segments = await self.redis_client.zrevrange(key, 0, -1) if not segments: return "" # 타임스탬프 제거하고 텍스트만 추출 texts = [] for seg in segments: parts = seg.split(":", 1) if len(parts) == 2: texts.append(parts[1]) # 시간순으로 정렬 (역순으로 조회했으므로 다시 뒤집기) return "\n".join(reversed(texts)) async def get_segment_count(self, meeting_id: str) -> int: """ 누적된 세그먼트 개수 Args: meeting_id: 회의 ID Returns: 세그먼트 개수 """ key = f"meeting:{meeting_id}:transcript" count = await self.redis_client.zcard(key) return count if count else 0 async def cleanup_meeting_data(self, meeting_id: str): """ 회의 종료 시 데이터 정리 Args: meeting_id: 회의 ID """ key = f"meeting:{meeting_id}:transcript" await self.redis_client.delete(key) logger.info(f"회의 데이터 정리 완료 - meetingId: {meeting_id}")