新增大量渠道适配器相关的协议、策略、工具类与基础设施代码,包括: 1. 多协议定义:认证、消息、配置、网关等核心接口 2. 策略模块:上下文、群聊、去重、防抖等业务策略 3. 工具集:重试、去重、文本分块、消息格式化等SDK工具 4. 基础设施:外部进程管理、事件广播、熔断机制等 5. 账户与管道系统:账户管理、消息处理管道实现 6. 运行时服务:状态收集、维护任务、日志等后台服务
43 lines
1.2 KiB
Python
43 lines
1.2 KiB
Python
from __future__ import annotations
|
|
|
|
import asyncio
|
|
import random
|
|
from collections.abc import Awaitable, Callable
|
|
from dataclasses import dataclass
|
|
from typing import Any
|
|
|
|
from yuxi.utils.logging_config import logger
|
|
|
|
|
|
@dataclass
|
|
class RetryConfig:
|
|
max_retries: int = 3
|
|
base_delay: float = 1.0
|
|
max_delay: float = 60.0
|
|
backoff_factor: float = 2.0
|
|
jitter: bool = True
|
|
retryable_exceptions: tuple[type[Exception], ...] = (Exception,)
|
|
|
|
|
|
async def with_retry(
|
|
func: Callable[[], Awaitable[Any]],
|
|
config: RetryConfig | None = None,
|
|
) -> Any:
|
|
cfg = config or RetryConfig()
|
|
last_exception: Exception | None = None
|
|
|
|
for attempt in range(cfg.max_retries + 1):
|
|
try:
|
|
return await func()
|
|
except cfg.retryable_exceptions as e:
|
|
last_exception = e
|
|
if attempt == cfg.max_retries:
|
|
break
|
|
delay = min(cfg.base_delay * (cfg.backoff_factor**attempt), cfg.max_delay)
|
|
if cfg.jitter:
|
|
delay *= random.uniform(0.5, 1.5)
|
|
logger.debug(f"[SDK/Retry] Attempt {attempt + 1}/{cfg.max_retries} failed: {e}, retrying in {delay:.2f}s")
|
|
await asyncio.sleep(delay)
|
|
|
|
raise last_exception # type: ignore[misc]
|