""" TaskResult - Handler 执行结果 统一的任务执行结果,用于所有 DataSource 的 Handler。 """ from enum import Enum from typing import Dict, Any, Optional class TaskStatus(Enum): """任务执行状态""" SUCCESS = "success" # 同步完成,立即成功 FAILED = "failed" # 同步失败 IN_PROGRESS = "in_progress" # 异步任务进行中 SKIPPED = "skipped" # 跳过(无实际更新或不符合更新条件) class TaskResult: """ Handler 执行结果 用于封装 create/update/delete 操作的返回值。 适用于所有 DataSource(API、JSONL 等)。 支持批量操作时通过 node_id 定位结果。 """ def __init__( self, status: TaskStatus, node_id: Optional[str] = None, data_id: Optional[str] = None, task_id: Optional[str] = None, push_id: Optional[str] = None, error: Optional[str] = None, sync_log: Optional[str] = None, metadata: Optional[Dict[str, Any]] = None ): """ Args: status: 任务状态(SUCCESS/FAILED/IN_PROGRESS) node_id: 关联的节点 ID(批量操作时用于定位节点) data_id: 成功时返回的业务 ID(CREATE 操作必需) task_id: 异步任务 ID(status=IN_PROGRESS 时必需) push_id: 推送请求 ID(用于统一 push/poll 跟踪) error: 失败原因(status=FAILED 时必需) sync_log: Debug/Info级别日志(SKIPPED时使用) metadata: 其他元数据 """ normalized_metadata = dict(metadata or {}) if push_id is None: raw_push_id = normalized_metadata.get("push_id") if isinstance(raw_push_id, str) and raw_push_id: push_id = raw_push_id elif push_id: normalized_metadata.setdefault("push_id", push_id) self.status = status self.node_id = node_id self.data_id = data_id self.task_id = task_id self.push_id = push_id self.error = error self.sync_log = sync_log self.metadata = normalized_metadata @classmethod def success( cls, node_id: Optional[str] = None, data_id: Optional[str] = None, push_id: Optional[str] = None, **metadata, ) -> "TaskResult": """创建成功结果""" return cls(TaskStatus.SUCCESS, node_id=node_id, data_id=data_id, push_id=push_id, metadata=metadata) @classmethod def failed( cls, node_id: Optional[str] = None, error: str = "", push_id: Optional[str] = None, **metadata, ) -> "TaskResult": """创建失败结果""" return cls(TaskStatus.FAILED, node_id=node_id, error=error, push_id=push_id, metadata=metadata) @classmethod def skipped( cls, node_id: Optional[str] = None, reason: str = "", push_id: Optional[str] = None, **metadata, ) -> "TaskResult": """创建跳过结果(无实际更新等)""" return cls(TaskStatus.SKIPPED, node_id=node_id, sync_log=reason, push_id=push_id, metadata=metadata) @classmethod def in_progress( cls, node_id: Optional[str] = None, task_id: str = "", push_id: Optional[str] = None, **metadata, ) -> "TaskResult": """创建进行中结果""" return cls(TaskStatus.IN_PROGRESS, node_id=node_id, task_id=task_id, push_id=push_id, metadata=metadata) def __repr__(self) -> str: parts = [f"status={self.status.value}"] if self.node_id: parts.append(f"node_id={self.node_id}") if self.data_id: parts.append(f"data_id={self.data_id}") if self.task_id: parts.append(f"task_id={self.task_id}") if self.push_id: parts.append(f"push_id={self.push_id}") if self.error: parts.append(f"error={self.error!r}") return f"TaskResult({', '.join(parts)})"