修复规则缓存写入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 threading
import time
from datetime import date, datetime
from typing import Any, Dict, List, Optional, Tuple
from loguru import logger
@@ -47,13 +48,32 @@ class FunCommandRuleService:
"""从 MySQL 回源全量启用规则。"""
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:
"""写入 Redis 持久缓存。
注意这里不设置过期时间Redis 作为跨进程共享缓存常驻。
"""
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:
logger.warning(f"写入 Redis 规则缓存失败: {e}")