Files
my-v0-server/app/services/persistence.py
T
2026-09-30 09:00:44 -07:00

74 lines
2.7 KiB
Python
Raw 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.
"""持久化装配:按配置选择 MongoDB 或进程内存,统一返回会话存储、检查点和关闭函数"""
from collections.abc import Awaitable, Callable
from dataclasses import dataclass
from typing import Any
from langgraph.checkpoint.base import BaseCheckpointSaver
from loguru import logger
from app.config import settings
from app.services.conversation import ConversationStore, InMemoryConversationStore
@dataclass
class Persistence:
store: ConversationStore
# 为空时由图使用默认的内存检查点
checkpointer: BaseCheckpointSaver | None
close: Callable[[], Awaitable[None]]
# 启用 MongoDB 时的数据库,供物料等其他集合复用同一连接
db: Any = None
async def _close_nothing() -> None:
return None
async def open_persistence() -> Persistence:
if not settings.mongodb_uri:
logger.warning(
"未配置 MONGODB_URI,会话记录和检查点仅保存在进程内存,重启后丢失"
)
return Persistence(InMemoryConversationStore(), None, _close_nothing)
# 依赖较重且只在启用 MongoDB 时使用,放到函数内导入
from langgraph.checkpoint.mongodb import MongoDBSaver
from pymongo import AsyncMongoClient, MongoClient
from app.processor.graph import build_checkpoint_serde
from app.services.conversation_mongo import MongoConversationStore
# 会话记录使用异步客户端;官方检查点基于同步客户端,异步方法由其放入线程池执行
async_client = AsyncMongoClient(settings.mongodb_uri, serverSelectionTimeoutMS=5000)
sync_client = MongoClient(settings.mongodb_uri, serverSelectionTimeoutMS=5000)
async def close() -> None:
try:
await async_client.close()
finally:
sync_client.close()
try:
# 启动时探测连接,配置错误尽早暴露;异常信息不包含连接串,避免泄露账号密码
try:
await async_client.admin.command("ping")
except Exception as exc:
raise RuntimeError(f"无法连接 MongoDB:{type(exc).__name__}") from None
store = MongoConversationStore(async_client[settings.mongodb_db])
await store.ensure_indexes()
# 与内存检查点共用同一份类型白名单,保证读回后仍是业务模型对象
checkpointer = MongoDBSaver(
sync_client,
settings.mongodb_db,
ttl=settings.mongodb_checkpoint_ttl or None,
serde=build_checkpoint_serde(),
)
except BaseException:
await close()
raise
logger.info("已启用 MongoDB 持久化,库名 {}", settings.mongodb_db)
return Persistence(store, checkpointer, close, async_client[settings.mongodb_db])