"""适配器管理服务 - 对应Go的internal/service/adapter.go""" import asyncio from datetime import datetime from typing import Dict, List, Optional, Callable from threading import RLock from app.models import ( AdapterListData, AdapterInfo, AdapterStatus, AdapterToggleRequest, AdapterConfigUpdateRequest ) from app.adapters import DataSourceAdapter, AKShareAdapter from app.core.logger import info, error class AdapterService: """适配器管理服务""" def __init__(self): self.lock = RLock() # 已注册的适配器工厂 self.factories: Dict[str, Callable[[], DataSourceAdapter]] = {} # 适配器配置 self.configs: Dict[str, dict] = {} # 当前激活的适配器实例 self.active_adapters: Dict[str, DataSourceAdapter] = {} # 适配器元数据 self.metadata: Dict[str, dict] = {} # 注册内置适配器 self._register_builtin_adapters() def _register_builtin_adapters(self): """注册内置适配器""" # 注册AKShare适配器 self.register_adapter("akshare", lambda: AKShareAdapter()) # 设置AKShare元数据 self.metadata["akshare"] = { "name": "akshare", "type": "http", "version": "1.0.0", "description": "AKShare 开源金融数据接口(无需Token)", "updated_at": datetime.now() } # AKShare默认配置(无需token) self.configs["akshare"] = { "enabled": True, "config": { "timeout": 30 } } def get_adapter_list(self) -> AdapterListData: """获取适配器列表""" with self.lock: adapters = [] for name, meta in self.metadata.items(): cfg = self.configs.get(name, {"enabled": False, "config": {}}) # 确定状态 if not cfg["enabled"]: status = AdapterStatus.DISABLED elif name in self.active_adapters: status = AdapterStatus.ACTIVE else: status = AdapterStatus.STANDBY adapters.append(AdapterInfo( name=meta["name"], type=meta["type"], version=meta["version"], description=meta["description"], status=status, config=cfg.get("config", {}), updated_at=meta.get("updated_at", datetime.now()) )) return AdapterListData(adapters=adapters) def toggle_adapter(self, req: AdapterToggleRequest) -> None: """启用/禁用适配器""" with self.lock: if req.name not in self.configs: raise ValueError(f"Adapter not found: {req.name}") self.configs[req.name]["enabled"] = req.enable # 如果禁用,关闭适配器连接 if not req.enable and req.name in self.active_adapters: adapter = self.active_adapters.pop(req.name) asyncio.create_task(adapter.close()) # 更新元数据 if req.name in self.metadata: self.metadata[req.name]["updated_at"] = datetime.now() def update_adapter_config(self, req: AdapterConfigUpdateRequest) -> None: """更新适配器配置""" with self.lock: if req.name not in self.configs: raise ValueError(f"Adapter not found: {req.name}") # 更新配置 self.configs[req.name]["config"].update(req.config) # 如果适配器已激活,重新连接 if req.name in self.active_adapters: adapter = self.active_adapters.pop(req.name) asyncio.create_task(adapter.close()) # 如果启用状态,重新连接 if self.configs[req.name]["enabled"]: asyncio.create_task(self._connect_adapter(req.name)) # 更新元数据 if req.name in self.metadata: self.metadata[req.name]["updated_at"] = datetime.now() def get_active_adapter(self, asset_class: str) -> Optional[DataSourceAdapter]: """获取当前激活的适配器""" with self.lock: # 使用 AKShare(唯一适配器) if "akshare" in self.active_adapters: return self.active_adapters["akshare"] # 如果没有激活的适配器,返回None,调用方需要负责初始化 return None def get_available_adapters(self) -> List[str]: """获取所有可用的适配器名称""" with self.lock: names = [] for name, meta in self.metadata.items(): if name in self.factories: names.append(f"{name}|{meta['description']}") return names def register_adapter(self, name: str, factory: Callable[[], DataSourceAdapter]): """注册适配器""" with self.lock: self.factories[name] = factory async def _connect_adapter(self, name: str): """连接适配器""" with self.lock: if name not in self.factories: raise ValueError(f"Adapter factory not found: {name}") if name not in self.configs: raise ValueError(f"Adapter config not found: {name}") factory = self.factories[name] cfg = self.configs[name] adapter = factory() await adapter.connect(cfg["config"]) with self.lock: self.active_adapters[name] = adapter async def health_check(self, name: str) -> bool: """适配器健康检查""" with self.lock: if name not in self.active_adapters: return False adapter = self.active_adapters[name] return await adapter.health_check()