feat:简化部分代码

This commit is contained in:
2026-09-29 07:23:42 -07:00
parent af84485e8d
commit 352d144823
13 changed files with 123 additions and 306 deletions
+22 -47
View File
@@ -1,15 +1,13 @@
import inspect
import time
from abc import ABC, abstractmethod
from typing import TYPE_CHECKING, TypeVar
from contextlib import contextmanager
from typing import TypeVar
from langgraph.errors import GraphInterrupt
from loguru import logger
from pydantic import ValidationError
if TYPE_CHECKING:
from app.config import Settings
from app.exceptions import AppError, ImportProcessError
from app.config import Settings, settings
from app.processor.progress import node_progress
T = TypeVar("T")
@@ -18,67 +16,44 @@ T = TypeVar("T")
class BaseNode(ABC):
name: str = "base_node"
def __init__(self, config: "Settings | None" = None):
"""保存显式配置;全局配置在节点实际使用时才加载。"""
self._config = config
def __init__(self, config: Settings | None = None):
self.config = config if config is not None else settings
self.logger = logger.bind(node=self.name)
@property
def config(self) -> "Settings":
if self._config is None:
from app.config import settings
self._config = settings
return self._config
def __call__(self, state: T) -> T:
"""执行节点,统一记录日志、耗时并保留业务异常类型"""
if inspect.iscoroutinefunction(self.process):
return self._acall(state)
@contextmanager
def _instrument(self, state):
"""统一记录日志、耗时和进度事件,异常保持原类型向上抛出"""
start_time = time.perf_counter()
self.logger.info("节点开始")
try:
with node_progress(self.name, state):
result = self.process(state)
yield
except GraphInterrupt:
raise
except (AppError, ValidationError):
except Exception:
self.logger.error("节点执行失败")
raise
except Exception as e:
self.logger.error("节点执行失败")
raise ImportProcessError(str(e), node_name=self.name) from e
else:
self.logger.info("节点完成")
return result
finally:
self.logger.info(f"节点耗时 {time.perf_counter() - start_time:.3f} 秒")
def __call__(self, state: T) -> T:
# 异步节点直接调用时返回协程,日志与进度在 _acall 内等待完成后记录
if inspect.iscoroutinefunction(self.process):
return self._acall(state)
with self._instrument(state):
return self.process(state)
async def _acall(self, state: T) -> T:
"""异步节点入口,由图根据 process 是否为协程选择"""
with self._instrument(state):
return await self.process(state)
@abstractmethod
def process(self, state: T) -> T:
"""子类实现节点核心逻辑,返回状态更新"""
async def _acall(self, state: T) -> T:
"""异步节点等待执行完成后再记录结果和耗时"""
start_time = time.perf_counter()
self.logger.info("节点开始")
try:
with node_progress(self.name, state):
result = await self.process(state)
except GraphInterrupt:
raise
except (AppError, ValidationError):
self.logger.error("节点执行失败")
raise
except Exception as error:
self.logger.error("节点执行失败")
raise ImportProcessError(str(error), node_name=self.name) from error
else:
self.logger.info("节点完成")
return result
finally:
self.logger.info(f"节点耗时 {time.perf_counter() - start_time:.3f} 秒")
def log_step(self, step_name: str, message: str = ""):
"""记录步骤日志。"""
log_msg = f"[{step_name}]"