113 lines
2.5 KiB
Python
113 lines
2.5 KiB
Python
from abc import abstractmethod, ABC
|
|
from typing import Generic, Optional, TypeVar
|
|
|
|
from pydantic import BaseModel
|
|
from pydantic_settings.main import asyncio
|
|
|
|
class HealthStatus(BaseModel):
|
|
"""
|
|
服务健康状态类
|
|
"""
|
|
service_name: str
|
|
is_initialized: bool = False
|
|
is_healthy: bool = False
|
|
detail: Optional[str] = None
|
|
|
|
T = TypeVar("T", bound="BaseService")
|
|
class BaseService(ABC, Generic[T]):
|
|
"""
|
|
基础服务类,定义了服务的基本状态和操作
|
|
"""
|
|
_lock: asyncio.Lock = asyncio.Lock()
|
|
_instance: Optional[T] = None
|
|
|
|
@property
|
|
@abstractmethod
|
|
def service_name(self) -> str:
|
|
"""
|
|
返回服务名称
|
|
"""
|
|
|
|
@abstractmethod
|
|
async def _initialize(self) -> T:
|
|
"""
|
|
初始化服务
|
|
"""
|
|
|
|
@abstractmethod
|
|
async def _shutdown(self) -> None:
|
|
"""
|
|
关闭服务
|
|
"""
|
|
|
|
@abstractmethod
|
|
async def _health_check(self) -> bool:
|
|
"""
|
|
健康检查服务
|
|
"""
|
|
|
|
async def check_health(self) -> HealthStatus:
|
|
"""
|
|
检查服务健康状态
|
|
"""
|
|
async with self._lock:
|
|
if self._instance is None:
|
|
return HealthStatus(
|
|
service_name=self.service_name,
|
|
is_initialized=False,
|
|
is_healthy=False,
|
|
)
|
|
try:
|
|
is_healthy = await self._health_check()
|
|
return HealthStatus(
|
|
service_name=self.service_name,
|
|
is_initialized=True,
|
|
is_healthy=is_healthy,
|
|
detail="success",
|
|
)
|
|
except Exception as e:
|
|
return HealthStatus(
|
|
service_name=self.service_name,
|
|
is_initialized=True,
|
|
is_healthy=False,
|
|
detail=str(e),
|
|
)
|
|
|
|
async def initialize(self) -> None:
|
|
"""
|
|
初始化服务
|
|
"""
|
|
async with self._lock:
|
|
if self._instance is not None:
|
|
await self._shutdown()
|
|
try:
|
|
self._instance = await self._initialize()
|
|
except Exception as e:
|
|
self._instance = None
|
|
raise e
|
|
|
|
async def shutdown(self) -> None:
|
|
"""
|
|
关闭服务
|
|
"""
|
|
async with self._lock:
|
|
if self._instance is None:
|
|
return
|
|
await self._shutdown()
|
|
self._instance = None
|
|
|
|
async def get_instance(self, force_initialize: bool = False) -> T:
|
|
"""
|
|
获取服务实例
|
|
"""
|
|
if self._instance is None and force_initialize:
|
|
await self.initialize()
|
|
if self._instance is None:
|
|
raise ValueError(f"Service {self.service_name} is not initialized.")
|
|
return self._instance
|
|
|
|
__all__ = [
|
|
"BaseService",
|
|
"HealthStatus",
|
|
]
|