123 lines
4.0 KiB
Python
123 lines
4.0 KiB
Python
"""
|
||
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)})"
|