Files
exchange_monitor_sync/sync/base_sync.py
lz_db c8a6cfead1 1
2025-12-02 22:36:52 +08:00

121 lines
4.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from abc import ABC, abstractmethod
from loguru import logger
from typing import List, Dict, Any, Set
import json
import re
from utils.redis_client import RedisClient
from utils.database_manager import DatabaseManager
from config.settings import COMPUTER_NAMES, COMPUTER_NAME_PATTERN
class BaseSync(ABC):
"""同步基类"""
def __init__(self):
self.redis_client = RedisClient()
self.db_manager = DatabaseManager()
self.computer_names = self._get_computer_names()
self.computer_name_pattern = re.compile(COMPUTER_NAME_PATTERN)
def _get_computer_names(self) -> List[str]:
"""获取计算机名列表"""
if ',' in COMPUTER_NAMES:
return [name.strip() for name in COMPUTER_NAMES.split(',')]
return [COMPUTER_NAMES.strip()]
def get_accounts_from_redis(self) -> Dict[str, Dict]:
"""从Redis获取所有计算机名的账号配置"""
try:
accounts_dict = {}
# 方法1使用配置的计算机名列表
for computer_name in self.computer_names:
accounts = self._get_accounts_by_computer_name(computer_name)
accounts_dict.update(accounts)
# 方法2自动发现所有匹配的key备用方案
if not accounts_dict:
accounts_dict = self._discover_all_accounts()
logger.info(f"{len(self.computer_names)} 个计算机名获取到 {len(accounts_dict)} 个账号")
return accounts_dict
except Exception as e:
logger.error(f"获取账户信息失败: {e}")
return {}
def _get_accounts_by_computer_name(self, computer_name: str) -> Dict[str, Dict]:
"""获取指定计算机名的账号"""
accounts_dict = {}
try:
# 构建key
redis_key = f"{computer_name}_strategy_api"
# 从Redis获取数据
result = self.redis_client.client.hgetall(redis_key)
if not result:
logger.debug(f"未找到 {redis_key} 的策略API配置")
return {}
for exchange_name, accounts_json in result.items():
try:
accounts = json.loads(accounts_json)
if not accounts:
continue
# 格式化交易所ID
exchange_id = self.format_exchange_id(exchange_name)
for account_id, account_info in accounts.items():
parsed_account = self.parse_account(exchange_id, account_id, account_info)
if parsed_account:
# 添加计算机名标记
parsed_account['computer_name'] = computer_name
accounts_dict[account_id] = parsed_account
except json.JSONDecodeError as e:
logger.error(f"解析交易所 {exchange_name} 的JSON数据失败: {e}")
continue
logger.info(f"{redis_key} 获取到 {len(accounts_dict)} 个账号")
except Exception as e:
logger.error(f"获取计算机名 {computer_name} 的账号失败: {e}")
return accounts_dict
def _discover_all_accounts(self) -> Dict[str, Dict]:
"""自动发现所有匹配的账号key"""
accounts_dict = {}
try:
# 获取所有匹配模式的key
pattern = f"*_strategy_api"
cursor = 0
while True:
cursor, keys = self.redis_client.client.scan(cursor, match=pattern, count=100)
for key in keys:
key_str = key.decode('utf-8') if isinstance(key, bytes) else key
# 提取计算机名
computer_name = key_str.replace('_strategy_api', '')
# 验证计算机名格式
if self.computer_name_pattern.match(computer_name):
accounts = self._get_accounts_by_computer_name(computer_name)
accounts_dict.update(accounts)
if cursor == 0:
break
logger.info(f"自动发现 {len(accounts_dict)} 个账号")
except Exception as e:
logger.error(f"自动发现账号失败: {e}")
return accounts_dict
# 其他方法保持不变...