Skip to main content
Glama
JDeun

Unified Search MCP Server

by JDeun
decorators.py4.69 kB
# src/cache/decorators.py """ 캐시 데코레이터 함수 결과를 자동으로 캐싱하는 데코레이터 """ import functools import inspect from typing import Optional, Callable, Any import logging from .manager import get_cache_manager logger = logging.getLogger(__name__) def cached( ttl: Optional[int] = None, source: Optional[str] = None, key_prefix: Optional[str] = None ): """ 캐시 데코레이터 Args: ttl: 캐시 TTL (초) source: 캐시 소스 (통계용) key_prefix: 키 프리픽스 """ def decorator(func: Callable) -> Callable: # 비동기 함수인지 확인 is_async = inspect.iscoroutinefunction(func) if is_async: @functools.wraps(func) async def async_wrapper(*args, **kwargs): cache_manager = get_cache_manager() # 캐시 키 생성 cache_key_data = { 'func': func.__name__, 'args': str(args), 'kwargs': str(sorted(kwargs.items())), 'source': source or func.__module__ } if key_prefix: cache_key_data['prefix'] = key_prefix cache_key = cache_manager.make_key(**cache_key_data) # 캐시 조회 cached_value = await cache_manager.get(cache_key) if cached_value is not None: logger.debug(f"캐시에서 반환: {func.__name__}") return cached_value # 함수 실행 result = await func(*args, **kwargs) # 캐시 저장 await cache_manager.set( cache_key, result, ttl=ttl, source=source ) return result return async_wrapper else: @functools.wraps(func) def sync_wrapper(*args, **kwargs): # 동기 함수는 캐싱하지 않음 (현재 비동기 전용) logger.warning(f"동기 함수 {func.__name__}에는 캐싱이 지원되지 않습니다") return func(*args, **kwargs) return sync_wrapper return decorator def invalidate_cache(source: Optional[str] = None): """ 캐시 무효화 데코레이터 함수 실행 후 특정 소스의 캐시를 무효화 Args: source: 무효화할 캐시 소스 (None이면 전체) """ def decorator(func: Callable) -> Callable: is_async = inspect.iscoroutinefunction(func) if is_async: @functools.wraps(func) async def async_wrapper(*args, **kwargs): # 함수 실행 result = await func(*args, **kwargs) # 캐시 무효화 cache_manager = get_cache_manager() await cache_manager.clear(source=source) logger.info(f"캐시 무효화됨: {source or '전체'}") return result return async_wrapper else: @functools.wraps(func) def sync_wrapper(*args, **kwargs): result = func(*args, **kwargs) logger.warning(f"동기 함수 {func.__name__}에서는 캐시 무효화가 지원되지 않습니다") return result return sync_wrapper return decorator class CacheKey: """캐시 키 생성 도우미""" @staticmethod def for_search(query: str, source: str, **filters) -> str: """검색용 캐시 키 생성""" cache_manager = get_cache_manager() return cache_manager.make_key( type='search', query=query, source=source, filters=filters ) @staticmethod def for_author(author_name: str) -> str: """저자 정보용 캐시 키 생성""" cache_manager = get_cache_manager() return cache_manager.make_key( type='author', author_name=author_name, source='scholar' ) @staticmethod def for_api_stats(service: str) -> str: """API 통계용 캐시 키 생성""" cache_manager = get_cache_manager() return cache_manager.make_key( type='api_stats', service=service, source='stats' )

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/JDeun/unified-search-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server