first commit

This commit is contained in:
2026-03-04 17:22:39 +08:00
commit 26a0b3507d
42 changed files with 1547 additions and 0 deletions

View File

@@ -0,0 +1,88 @@
import asyncio
import functools
from typing import Callable, Any, TypeVar, Coroutine
from wechat_auto.utils.logger import logger
from wechat_auto.config import settings
T = TypeVar('T')
def async_retry(
max_retries: int = None,
base_delay: float = None,
exponential: bool = True,
exceptions: tuple = (Exception,)
):
max_retries = max_retries or settings.max_retries
base_delay = base_delay or settings.retry_base_delay
def decorator(func: Callable[..., Coroutine[Any, Any, T]]):
@functools.wraps(func)
async def wrapper(*args, **kwargs) -> T:
last_exception = None
for attempt in range(max_retries):
try:
return await func(*args, **kwargs)
except exceptions as e:
last_exception = e
if attempt < max_retries - 1:
if exponential:
delay = base_delay * (2 ** attempt)
else:
delay = base_delay
logger.warning(
f"{func.__name__} 失败,{attempt + 1}/{max_retries}"
f"{delay:.1f}秒后重试: {e}"
)
await asyncio.sleep(delay)
else:
logger.error(
f"{func.__name__} 失败,已达到最大重试次数 {max_retries}: {e}"
)
raise last_exception
return wrapper
return decorator
def sync_retry(
max_retries: int = None,
base_delay: float = None,
exponential: bool = True,
exceptions: tuple = (Exception,)
):
max_retries = max_retries or settings.max_retries
base_delay = base_delay or settings.retry_base_delay
def decorator(func: Callable[..., T]):
@functools.wraps(func)
def wrapper(*args, **kwargs) -> T:
last_exception = None
for attempt in range(max_retries):
try:
return func(*args, **kwargs)
except exceptions as e:
last_exception = e
if attempt < max_retries - 1:
if exponential:
delay = base_delay * (2 ** attempt)
else:
delay = base_delay
logger.warning(
f"{func.__name__} 失败,{attempt + 1}/{max_retries}"
f"{delay:.1f}秒后重试: {e}"
)
import time
time.sleep(delay)
else:
logger.error(
f"{func.__name__} 失败,已达到最大重试次数 {max_retries}: {e}"
)
raise last_exception
return wrapper
return decorator