Files
a_long/utils/celery_utils.py
2026-06-14 02:38:05 +08:00

110 lines
3.4 KiB
Python
Raw Permalink 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.
"""
阿龙电竞 - Celery工具函数
提供通用的Celery辅助函数确保数据安全和操作稳定
"""
import logging
from django.db import transaction
from datetime import datetime
from decimal import Decimal, InvalidOperation
# 配置日志
logger = logging.getLogger(__name__)
def safe_decimal_operation(value, default=Decimal('0.00')):
"""
安全处理Decimal操作防止类型转换错误
:param value: 输入值
:param default: 默认值
:return: Decimal对象
"""
try:
if value is None:
return default
if isinstance(value, Decimal):
return value
if isinstance(value, (int, float)):
return Decimal(str(value))
if isinstance(value, str):
# 移除可能的空白字符和特殊字符
value = value.strip()
if not value:
return default
return Decimal(value)
# 其他类型尝试转换
return Decimal(str(value))
except (InvalidOperation, TypeError, ValueError) as e:
logger.warning(f"Decimal转换失败: {e}, 输入值: {value}, 类型: {type(value)}, 使用默认值: {default}")
return default
except Exception as e:
logger.error(f"Decimal转换发生未知错误: {e}, 输入值: {value}, 使用默认值: {default}")
return default
def log_task_execution(task_name, success=True, details=""):
"""
记录任务执行日志
:param task_name: 任务名称
:param success: 是否成功
:param details: 详细信息
"""
try:
timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
status = "成功" if success else "失败"
log_message = f"[{timestamp}] {task_name} - {status}"
if details:
log_message += f" | {details}"
if success:
logger.info(log_message)
else:
logger.error(log_message)
return log_message
except Exception as e:
# 即使日志记录失败也不影响主流程
print(f"日志记录失败: {e}")
return f"日志记录失败: {e}"
def rollback_on_failure(operation_name):
"""
事务回滚装饰器
:param operation_name: 操作名称
"""
def decorator(func):
def wrapper(*args, **kwargs):
try:
with transaction.atomic():
return func(*args, **kwargs)
except Exception as e:
logger.error(f"{operation_name}事务执行失败: {str(e)}")
raise
return wrapper
return decorator
def retry_on_failure(max_retries=3, delay=60):
"""
重试装饰器可用于Celery任务
:param max_retries: 最大重试次数
:param delay: 重试延迟(秒)
"""
def decorator(func):
def wrapper(*args, **kwargs):
retries = 0
while retries < max_retries:
try:
return func(*args, **kwargs)
except Exception as e:
retries += 1
if retries == max_retries:
logger.error(f"任务{func.__name__}重试{max_retries}次后失败: {str(e)}")
raise
logger.warning(f"任务{func.__name__}{retries}次失败,{delay}秒后重试: {str(e)}")
import time
time.sleep(delay)
return wrapper
return decorator