修复规则缓存写入Redis时datetime序列化异常

1. 在规则服务中新增JSON安全转换逻辑,递归处理dict/list结构。

2. 将datetime/date统一转换为字符串后再写入Redis,避免Object of type datetime is not JSON serializable。

3. 保持缓存结构兼容,不影响现有规则匹配流程。
This commit is contained in:
liuwei
2026-04-23 13:39:43 +08:00
parent cd56723090
commit df6f9f4cfa

View File

@@ -11,6 +11,7 @@ import json
import re import re
import threading import threading
import time import time
from datetime import date, datetime
from typing import Any, Dict, List, Optional, Tuple from typing import Any, Dict, List, Optional, Tuple
from loguru import logger from loguru import logger
@@ -47,13 +48,32 @@ class FunCommandRuleService:
"""从 MySQL 回源全量启用规则。""" """从 MySQL 回源全量启用规则。"""
return self.db.list_rules(enabled=True) return self.db.list_rules(enabled=True)
def _make_json_safe(self, value: Any) -> Any:
"""将任意对象转换为可 JSON 序列化结构。
重点处理:
1. datetime/date统一转成字符串避免 json.dumps 抛异常。
2. dict/list递归处理确保嵌套结构中的时间字段也可序列化。
"""
if isinstance(value, datetime):
return value.strftime("%Y-%m-%d %H:%M:%S")
if isinstance(value, date):
return value.strftime("%Y-%m-%d")
if isinstance(value, dict):
return {str(k): self._make_json_safe(v) for k, v in value.items()}
if isinstance(value, list):
return [self._make_json_safe(item) for item in value]
return value
def _write_redis_rules(self, rules: List[Dict[str, Any]]) -> None: def _write_redis_rules(self, rules: List[Dict[str, Any]]) -> None:
"""写入 Redis 持久缓存。 """写入 Redis 持久缓存。
注意这里不设置过期时间Redis 作为跨进程共享缓存常驻。 注意这里不设置过期时间Redis 作为跨进程共享缓存常驻。
""" """
try: try:
self.redis.set(self.REDIS_RULES_KEY, json.dumps(rules or [], ensure_ascii=False)) # 规则行里可能带 created_at/updated_at(datetime),这里先做 JSON 安全转换。
safe_rules = self._make_json_safe(rules or [])
self.redis.set(self.REDIS_RULES_KEY, json.dumps(safe_rules, ensure_ascii=False))
except Exception as e: except Exception as e:
logger.warning(f"写入 Redis 规则缓存失败: {e}") logger.warning(f"写入 Redis 规则缓存失败: {e}")