You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

154 lines
5.0 KiB

"""
SDK连接管理器 - 保持SDK登录状态避免重复登录
"""
import threading
import time
from typing import Optional, Dict, Any
from app.services.amazing_data_adapter import AmazingDataAdapter
from app.models.config import SDKConfig
from app.db.session import SessionLocal
import logging
logger = logging.getLogger(__name__)
class SDKConnectionManager:
"""
SDK连接管理器
- 保持SDK登录状态避免重复登录
- 登录成功后在释放前所有请求都不用重复登录
- 支持多配置管理
"""
_instance = None
_lock = threading.Lock()
def __new__(cls):
if cls._instance is None:
with cls._lock:
if cls._instance is None:
cls._instance = super().__new__(cls)
cls._instance._connections: Dict[int, AmazingDataAdapter] = {}
cls._instance._connection_locks: Dict[int, threading.Lock] = {}
cls._instance._last_activity: Dict[int, float] = {}
return cls._instance
def get_connection(self, config_id: int) -> Optional[AmazingDataAdapter]:
"""
获取SDK连接
Args:
config_id: 配置ID
Returns:
AmazingDataAdapter实例如果连接失败返回None
"""
if config_id not in self._connection_locks:
self._connection_locks[config_id] = threading.Lock()
with self._connection_locks[config_id]:
if config_id in self._connections:
adapter = self._connections[config_id]
if adapter.is_connected():
self._last_activity[config_id] = time.time()
return adapter
else:
del self._connections[config_id]
db = SessionLocal()
try:
config = db.query(SDKConfig).filter(SDKConfig.id == config_id).first()
if not config:
logger.warning(f"SDK配置不存在: {config_id}")
return None
adapter = AmazingDataAdapter({
"username": config.username,
"password": config.password,
"host": config.host,
"port": config.port,
"local_path": config.local_path or "./amazing_data_cache/"
})
if adapter.connect():
self._connections[config_id] = adapter
self._last_activity[config_id] = time.time()
logger.info(f"SDK连接成功: config_id={config_id}")
return adapter
else:
logger.warning(f"SDK连接失败: config_id={config_id}")
return None
finally:
db.close()
def release_connection(self, config_id: int):
"""
释放SDK连接
Args:
config_id: 配置ID
"""
if config_id not in self._connection_locks:
return
with self._connection_locks[config_id]:
if config_id in self._connections:
adapter = self._connections[config_id]
try:
adapter.disconnect()
logger.info(f"SDK连接已释放: config_id={config_id}")
except Exception as e:
logger.warning(f"释放SDK连接时出错: {e}")
del self._connections[config_id]
if config_id in self._last_activity:
del self._last_activity[config_id]
def get_default_connection(self) -> Optional[AmazingDataAdapter]:
"""
获取默认SDK连接
Returns:
AmazingDataAdapter实例
"""
db = SessionLocal()
try:
config = db.query(SDKConfig).filter(SDKConfig.is_default == True).first()
if not config:
config = db.query(SDKConfig).first()
if config:
return self.get_connection(config.id)
return None
finally:
db.close()
def release_all(self):
"""释放所有SDK连接"""
for config_id in list(self._connections.keys()):
self.release_connection(config_id)
def get_status(self, config_id: int) -> Dict[str, Any]:
"""
获取连接状态
Args:
config_id: 配置ID
Returns:
状态信息
"""
if config_id in self._connections:
adapter = self._connections[config_id]
return {
"connected": adapter.is_connected(),
"last_activity": self._last_activity.get(config_id, 0),
"config_id": config_id
}
return {
"connected": False,
"last_activity": 0,
"config_id": config_id
}
sdk_manager = SDKConnectionManager()