1407 lines
60 KiB
Python
1407 lines
60 KiB
Python
import logging
|
||
from typing import Dict, Any
|
||
from services.execution.task_context import TaskContext
|
||
|
||
|
||
from .base import BlockHandler, register_handler
|
||
from utils.logger import get_logger
|
||
from data.enum.task_block_record_enum import TaskBlockRecordStatus
|
||
from .model.block_name import ProgressBlockName
|
||
# 获取日志记录器
|
||
logger = get_logger("services.execution.handlers.progress")
|
||
|
||
# 条件判断块处理器
|
||
@register_handler(ProgressBlockName.IF)
|
||
class IfBlockHandler(BlockHandler):
|
||
"""条件判断块处理器"""
|
||
|
||
async def execute(
|
||
self,
|
||
block: Dict[str, Any],
|
||
input_params: Dict[str, Any],
|
||
context: TaskContext
|
||
) -> Dict[str, Any]:
|
||
"""执行条件判断块"""
|
||
try:
|
||
# 获取条件参数
|
||
condition = input_params.get("condition")
|
||
# 判断条件
|
||
result = bool(condition)
|
||
|
||
# 创建块执行器
|
||
from services.execution.block_executor import BlockExecutor
|
||
executor = BlockExecutor(context)
|
||
# 检查块中所有可用的分支
|
||
children = block.get("children", {})
|
||
has_true_branch = "true" in children and children["true"]
|
||
has_false_branch = "false" in children and children["false"]
|
||
has_default_branch = "default" in children and children["default"]
|
||
|
||
logger.info(f"条件判断块执行 - ID: {block.get('id')}, 条件结果: {result}")
|
||
if result:
|
||
# 条件为真,为false分支创建未执行记录
|
||
if has_false_branch:
|
||
logger.info(f"条件为真,为false分支创建未执行记录")
|
||
await self._create_not_executed_records(executor, block, "false", "条件为真,不执行false分支")
|
||
|
||
# 条件为真,优先执行true分支,如果没有则尝试执行default分支
|
||
if has_true_branch:
|
||
logger.info(f"条件为真,执行true分支")
|
||
branch_name = "true"
|
||
elif has_default_branch:
|
||
logger.info(f"条件为真但无true分支,执行default分支")
|
||
branch_name = "default"
|
||
else:
|
||
logger.info(f"条件为真但无可执行分支")
|
||
exec_result = {
|
||
"success": True,
|
||
"message": "条件为真,但没有找到true或default分支",
|
||
"output": {
|
||
"condition": result,
|
||
"branch": "none",
|
||
"executed": False
|
||
}
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, exec_result, context)
|
||
return exec_result
|
||
else:
|
||
# 条件为假,为true分支创建未执行记录
|
||
if has_true_branch:
|
||
logger.info(f"条件为假,为true分支创建未执行记录")
|
||
await self._create_not_executed_records(executor, block, "true", "条件为假,不执行true分支")
|
||
|
||
# 条件为假,为default分支创建未执行记录(如果true分支不存在但default存在)
|
||
if not has_true_branch and has_default_branch:
|
||
logger.info(f"条件为假,为default分支创建未执行记录")
|
||
await self._create_not_executed_records(executor, block, "default", "条件为假,不执行default分支")
|
||
|
||
# 条件为假,优先执行false分支
|
||
if has_false_branch:
|
||
logger.info(f"条件为假,执行false分支")
|
||
branch_name = "false"
|
||
else:
|
||
logger.info(f"条件为假且无false分支,不执行任何分支")
|
||
exec_result = {
|
||
"success": True,
|
||
"message": "条件为假,没有找到false分支",
|
||
"output": {
|
||
"condition": result,
|
||
"branch": "none",
|
||
"executed": False
|
||
}
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, exec_result, context)
|
||
return exec_result
|
||
# 执行选定的分支
|
||
if branch_name:
|
||
branch_result = await executor.execute_children(block, branch_name)
|
||
if not branch_result.get("success", False):
|
||
logger.error(f"分支 {branch_name} 执行失败: {branch_result.get('message')}")
|
||
# 记录执行结果
|
||
await self._record_task_log(block, branch_result, context)
|
||
return branch_result
|
||
|
||
logger.info(f"分支 {branch_name} 执行成功")
|
||
exec_result = {
|
||
"success": True,
|
||
"message": f"条件判断成功,执行{branch_name}分支完成",
|
||
"output": {
|
||
"condition": result,
|
||
"branch": branch_name,
|
||
"executed": True
|
||
}
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, exec_result, context)
|
||
return exec_result
|
||
|
||
# 正常情况不应该到达这里
|
||
exec_result = {
|
||
"success": True,
|
||
"message": "条件判断完成,未执行任何分支",
|
||
"output": {
|
||
"condition": result,
|
||
"branch": "none",
|
||
"executed": False
|
||
}
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, exec_result, context)
|
||
return exec_result
|
||
except Exception as e:
|
||
logger.error(f"条件判断执行异常: {str(e)}")
|
||
exec_result = {
|
||
"success": False,
|
||
"message": f"条件判断失败: {str(e)}"
|
||
}
|
||
# 记录异常
|
||
await self._record_task_log(block, exec_result, context)
|
||
return exec_result
|
||
|
||
async def _create_not_executed_records(self, executor, block, branch_name, reason):
|
||
"""
|
||
为指定分支的所有子组件创建未执行状态的记录
|
||
|
||
Args:
|
||
executor: 块执行器
|
||
block: 父块定义
|
||
branch_name: 分支名称
|
||
reason: 未执行原因
|
||
"""
|
||
try:
|
||
# 获取分支下的所有子块
|
||
children = block.get("children", {}).get(branch_name, [])
|
||
|
||
if not children:
|
||
logger.info(f"分支 {branch_name} 下没有子块,无需创建未执行记录")
|
||
return
|
||
|
||
logger.info(f"为分支 {branch_name} 下的 {len(children)} 个子块创建未执行记录")
|
||
|
||
# 依次为每个子块创建记录
|
||
for i, child_block in enumerate(children):
|
||
child_id = child_block.get('id', 'unknown')
|
||
child_type = child_block.get('blockType', 'unknown')
|
||
child_name = child_block.get('name', f"block-{child_id}")
|
||
|
||
logger.info(f"为未执行的子块创建记录 [{i+1}/{len(children)}] - 名称: {child_name}, ID: {child_id}, 类型: {child_type}")
|
||
|
||
# 创建子块记录
|
||
block_record_id = await executor._create_block_record(child_block)
|
||
|
||
# 更新块记录状态为"未执行"
|
||
await executor._update_block_record(
|
||
block_record_id,
|
||
TaskBlockRecordStatus.NOT_EXECUTED, # 使用1002表示"未执行"状态
|
||
reason,
|
||
)
|
||
|
||
# 如果该子块还有子块,递归处理
|
||
if "children" in child_block and child_block.get("children"):
|
||
# 对每个可能的分支都创建未执行记录
|
||
for sub_branch_name, sub_children in child_block.get("children", {}).items():
|
||
if sub_children:
|
||
sub_reason = f"{reason},父块未执行"
|
||
await self._create_not_executed_records(executor, child_block, sub_branch_name, sub_reason)
|
||
|
||
except Exception as e:
|
||
logger.error(f"创建未执行记录失败: {str(e)}")
|
||
# 继续执行,不影响主流程
|
||
|
||
# 循环块处理器
|
||
@register_handler(ProgressBlockName.WHILE)
|
||
class WhileBlockHandler(BlockHandler):
|
||
"""循环块处理器"""
|
||
|
||
async def execute(
|
||
self,
|
||
block: Dict[str, Any],
|
||
input_params: Dict[str, Any],
|
||
context: TaskContext
|
||
) -> Dict[str, Any]:
|
||
"""执行循环块"""
|
||
try:
|
||
# 获取循环条件和相关配置
|
||
loop_condition = input_params.get("loopCondition", False)
|
||
run_once = input_params.get("runOnce")
|
||
run_once = False if run_once is None else run_once # 是否至少执行一次
|
||
|
||
retry_period = input_params.get("retryPeriod")
|
||
retry_period = 0 if retry_period is None else retry_period # 循环间隔(毫秒)
|
||
|
||
print_continuously = input_params.get("printContinuously")
|
||
print_continuously = False if print_continuously is None else print_continuously # 是否持续打印日志
|
||
print("loop_condition", loop_condition, "=============================================")
|
||
print("run_once", run_once, "=============================================")
|
||
print("retry_period", retry_period, "=============================================")
|
||
print("print_continuously", print_continuously, "=============================================")
|
||
# 迭代计数器
|
||
iterations = 0
|
||
|
||
# 创建块执行器
|
||
from services.execution.block_executor import BlockExecutor
|
||
executor = BlockExecutor(context)
|
||
|
||
# 获取当前循环块的ID和名称,用于后续识别哪个break组件是作用于当前循环
|
||
current_loop_id = block.get("id")
|
||
current_loop_name = block.get("name")
|
||
|
||
logger.info(f"开始执行while循环块 - ID: {current_loop_id}, 名称: {current_loop_name}")
|
||
|
||
# 检查是否至少需要执行一次
|
||
if run_once:
|
||
# 执行一次循环体,无论条件是否满足
|
||
logger.info(f"执行while循环体(至少执行一次模式)")
|
||
branch_result = await executor.execute_children(block, "default")
|
||
if not branch_result.get("success", False):
|
||
# 记录执行结果
|
||
await self._record_task_log(block, branch_result, context)
|
||
return branch_result
|
||
iterations += 1
|
||
|
||
# 检查第一次执行后是否有break信号
|
||
has_break = await self._check_for_break_signal(block, context)
|
||
if has_break:
|
||
logger.info(f"while循环(至少执行一次模式)检测到break信号,提前结束循环")
|
||
break_result = {
|
||
"success": True,
|
||
"message": f"while循环第1次执行后检测到break信号,提前结束循环",
|
||
"output": {
|
||
"iterations": iterations
|
||
}
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, break_result, context)
|
||
|
||
# 执行exit分支(如果有)
|
||
if "exit" in block.get("children", {}) and block["children"]["exit"]:
|
||
logger.info(f"循环被break中断,执行exit分支")
|
||
await executor.execute_children(block, "exit")
|
||
|
||
return break_result
|
||
|
||
# 根据条件循环执行,不设最大迭代次数
|
||
while loop_condition:
|
||
# 检查是否取消
|
||
if context.is_task_canceled():
|
||
result = {
|
||
"success": False,
|
||
"message": "任务已被取消",
|
||
"is_canceled": True
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
|
||
# 检查是否有返回信号
|
||
if context.get_variable("__RETURN__", False):
|
||
logger.info(f"检测到返回信号,提前结束循环,已完成 {iterations} 次")
|
||
# 不重置返回信号,它需要向上传播
|
||
break
|
||
|
||
# 如果不是第一次执行且有重试间隔,则等待
|
||
if iterations > 0 and retry_period > 0:
|
||
import asyncio
|
||
await asyncio.sleep(retry_period / 1000)
|
||
else:
|
||
# 即使没有重试间隔,也强制每10次迭代释放一次事件循环
|
||
# 这确保了其他请求能够得到处理
|
||
if iterations % 10 == 0:
|
||
import asyncio
|
||
await asyncio.sleep(0.2) # 释放事件循环的最小时间
|
||
|
||
# 执行循环体
|
||
if print_continuously or iterations == 0:
|
||
logger.info(f"执行while循环体,第 {iterations+1} 次迭代")
|
||
|
||
branch_result = await executor.execute_children(block, "default")
|
||
if not branch_result.get("success", False):
|
||
# 记录执行结果
|
||
await self._record_task_log(block, branch_result, context)
|
||
return branch_result
|
||
|
||
iterations += 1
|
||
|
||
# 检查是否有break信号
|
||
has_break = await self._check_for_break_signal(block, context)
|
||
if has_break:
|
||
logger.info(f"while循环检测到break信号,提前结束循环,已完成 {iterations} 次")
|
||
break
|
||
|
||
# 重新获取循环条件
|
||
loop_condition = input_params.get("loopCondition", False)
|
||
|
||
# 循环结束后,执行exit分支
|
||
if "exit" in block.get("children", {}) and block["children"]["exit"]:
|
||
logger.info(f"循环结束,执行exit分支")
|
||
exit_result = await executor.execute_children(block, "exit")
|
||
if not exit_result.get("success", False):
|
||
# 记录执行结果
|
||
await self._record_task_log(block, exit_result, context)
|
||
return exit_result
|
||
|
||
result = {
|
||
"success": True,
|
||
"message": f"循环执行成功,共执行 {iterations} 次",
|
||
"output": {
|
||
"iterations": iterations
|
||
}
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
except Exception as e:
|
||
result = {
|
||
"success": False,
|
||
"message": f"循环执行失败: {str(e)}"
|
||
}
|
||
# 记录异常
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
|
||
async def _check_for_break_signal(self, block: Dict[str, Any], context: TaskContext) -> bool:
|
||
"""
|
||
检查是否有break信号
|
||
|
||
Args:
|
||
block: 当前块定义
|
||
context: 任务上下文
|
||
|
||
Returns:
|
||
bool: 是否有break信号
|
||
"""
|
||
try:
|
||
# 遍历当前循环的子组件,查找是否存在break组件及其执行情况
|
||
child_blocks = block.get("children", {}).get("default", [])
|
||
for child_block in child_blocks:
|
||
child_id = child_block.get("id")
|
||
child_name = child_block.get("name")
|
||
child_type = child_block.get("blockType")
|
||
|
||
# 直接子组件是break组件
|
||
if child_type == ProgressBlockName.BREAK:
|
||
# 检查该break组件是否执行过,通过查询其输出
|
||
break_output = context.get_block_output(child_name)
|
||
if break_output and break_output.get("breakSignal"):
|
||
logger.info(f"检测到直接子组件break信号 - 组件名称: {child_name}, ID: {child_id}")
|
||
return True
|
||
|
||
# 子组件不是循环块(因为嵌套循环内的break应作用于内层循环)
|
||
elif child_type not in [ProgressBlockName.WHILE, ProgressBlockName.ITERATE_LIST, ProgressBlockName.REPEAT_NUM]:
|
||
# 递归检查子组件的子组件中是否有break
|
||
if "children" in child_block and child_block.get("children") and await self._check_nested_break(child_block, context):
|
||
logger.info(f"检测到嵌套break信号,来自子组件 - 组件名称: {child_name}, ID: {child_id}")
|
||
return True
|
||
|
||
# 没有找到break信号
|
||
return False
|
||
except Exception as e:
|
||
logger.error(f"检查break信号失败: {str(e)}")
|
||
return False
|
||
|
||
async def _check_nested_break(self, block: Dict[str, Any], context: TaskContext) -> bool:
|
||
"""
|
||
递归检查嵌套组件中是否存在已执行的break组件
|
||
|
||
Args:
|
||
block: 要检查的块定义
|
||
context: 任务上下文
|
||
|
||
Returns:
|
||
bool: 是否存在已执行的break组件
|
||
"""
|
||
try:
|
||
# 获取所有可能的分支名称
|
||
branches = block.get("children", {}).keys()
|
||
|
||
# 遍历所有分支
|
||
for branch_name in branches:
|
||
branch_blocks = block.get("children", {}).get(branch_name, [])
|
||
|
||
# 遍历分支中的所有块
|
||
for child_block in branch_blocks:
|
||
child_id = child_block.get("id")
|
||
child_name = child_block.get("name")
|
||
child_type = child_block.get("blockType")
|
||
|
||
# 如果子块是循环块,则不继续向下递归检查
|
||
# 因为如果存在break,应该作用于最近的循环块而不是外层循环
|
||
if child_type in [ProgressBlockName.WHILE, ProgressBlockName.ITERATE_LIST, ProgressBlockName.REPEAT_NUM]:
|
||
logger.info(f"检测到嵌套循环块,不向下递归 - 类型: {child_type}, 名称: {child_name}")
|
||
continue
|
||
|
||
# 子块是break块
|
||
elif child_type == ProgressBlockName.BREAK:
|
||
# 检查该break组件是否执行过,通过查询其输出
|
||
break_output = context.get_block_output(child_name)
|
||
if break_output and break_output.get("breakSignal"):
|
||
logger.info(f"检测到嵌套break信号 - 组件名称: {child_name}, ID: {child_id}")
|
||
return True
|
||
|
||
# 子块是其他可能包含子组件的块(除了循环块)
|
||
elif "children" in child_block and child_block.get("children"):
|
||
# 递归检查子块中是否有break
|
||
if await self._check_nested_break(child_block, context):
|
||
return True
|
||
|
||
# 没有找到break信号
|
||
return False
|
||
except Exception as e:
|
||
logger.error(f"检查嵌套break组件失败: {str(e)}")
|
||
return False
|
||
|
||
# 等待块处理器
|
||
@register_handler(ProgressBlockName.WAIT)
|
||
class WaitBlockHandler(BlockHandler):
|
||
"""等待块处理器"""
|
||
|
||
async def execute(
|
||
self,
|
||
block: Dict[str, Any],
|
||
input_params: Dict[str, Any],
|
||
context: TaskContext
|
||
) -> Dict[str, Any]:
|
||
"""执行等待块"""
|
||
import asyncio
|
||
|
||
try:
|
||
# 获取等待时间参数(毫秒)
|
||
timeout = input_params.get("timeout", 1000)
|
||
|
||
# 确保timeout是数字
|
||
try:
|
||
# 转换为整数
|
||
if isinstance(timeout, str):
|
||
timeout = int(timeout)
|
||
|
||
# 转换为秒
|
||
timeout_sec = timeout / 1000
|
||
|
||
# 等待
|
||
await asyncio.sleep(timeout_sec)
|
||
|
||
result = {
|
||
"success": True,
|
||
"message": f"等待 {timeout} 毫秒完成",
|
||
"output": {
|
||
"timeout": timeout
|
||
}
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
except ValueError:
|
||
# 参数转换失败
|
||
result = {
|
||
"success": False,
|
||
"message": f"等待执行失败: 无效的等待时间参数 '{timeout}'"
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
except Exception as e:
|
||
result = {
|
||
"success": False,
|
||
"message": f"等待执行失败: {str(e)}"
|
||
}
|
||
# 记录异常
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
|
||
|
||
@register_handler(ProgressBlockName.IF_ELSE)
|
||
class IfElseBlockHandler(BlockHandler):
|
||
"""If-Else处理器"""
|
||
|
||
async def execute(
|
||
self,
|
||
block: Dict[str, Any],
|
||
input_params: Dict[str, Any],
|
||
context: TaskContext
|
||
) -> Dict[str, Any]:
|
||
"""执行If-Else条件判断块"""
|
||
try:
|
||
# 获取条件参数
|
||
condition = input_params.get("conditionIf")
|
||
|
||
# 创建块执行器
|
||
from services.execution.block_executor import BlockExecutor
|
||
executor = BlockExecutor(context)
|
||
|
||
# 根据条件执行不同分支
|
||
if condition:
|
||
# 条件为真,为else分支创建未执行记录
|
||
logger.info(f"条件为真,为else分支创建未执行记录")
|
||
await self._create_not_executed_records(executor, block, "else", "条件为真,不执行else分支")
|
||
|
||
# 执行if分支
|
||
branch_result = await executor.execute_children(block, "if")
|
||
if not branch_result.get("success", False):
|
||
# 记录执行结果
|
||
await self._record_task_log(block, branch_result, context)
|
||
return branch_result
|
||
|
||
result = {
|
||
"success": True,
|
||
"message": "条件为真,执行if分支成功",
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
else:
|
||
# 条件为假,为if分支创建未执行记录
|
||
logger.info(f"条件为假,为if分支创建未执行记录")
|
||
await self._create_not_executed_records(executor, block, "if", "条件为假,不执行if分支")
|
||
|
||
# 执行else分支
|
||
branch_result = await executor.execute_children(block, "else")
|
||
if not branch_result.get("success", False):
|
||
# 记录执行结果
|
||
await self._record_task_log(block, branch_result, context)
|
||
return branch_result
|
||
|
||
result = {
|
||
"success": True,
|
||
"message": "条件为假,执行else分支成功",
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
except Exception as e:
|
||
result = {
|
||
"success": False,
|
||
"message": f"If-Else条件判断执行失败: {str(e)}"
|
||
}
|
||
# 记录异常
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
|
||
async def _create_not_executed_records(self, executor, block, branch_name, reason):
|
||
"""
|
||
为指定分支的所有子组件创建未执行状态的记录
|
||
|
||
Args:
|
||
executor: 块执行器
|
||
block: 父块定义
|
||
branch_name: 分支名称
|
||
reason: 未执行原因
|
||
"""
|
||
try:
|
||
# 获取分支下的所有子块
|
||
children = block.get("children", {}).get(branch_name, [])
|
||
|
||
if not children:
|
||
logger.info(f"分支 {branch_name} 下没有子块,无需创建未执行记录")
|
||
return
|
||
|
||
logger.info(f"为分支 {branch_name} 下的 {len(children)} 个子块创建未执行记录")
|
||
|
||
# 依次为每个子块创建记录
|
||
for i, child_block in enumerate(children):
|
||
child_id = child_block.get('id', 'unknown')
|
||
child_type = child_block.get('blockType', 'unknown')
|
||
child_name = child_block.get('name', f"block-{child_id}")
|
||
|
||
logger.info(f"为未执行的子块创建记录 [{i+1}/{len(children)}] - 名称: {child_name}, ID: {child_id}, 类型: {child_type}")
|
||
|
||
# 创建子块记录
|
||
block_record_id = await executor._create_block_record(child_block)
|
||
|
||
# 更新块记录状态为"未执行"
|
||
await executor._update_block_record(
|
||
block_record_id,
|
||
TaskBlockRecordStatus.NOT_EXECUTED, # 使用1006表示"未执行"状态
|
||
reason,
|
||
)
|
||
|
||
# 如果该子块还有子块,递归处理
|
||
if "children" in child_block and child_block.get("children"):
|
||
# 对每个可能的分支都创建未执行记录
|
||
for sub_branch_name, sub_children in child_block.get("children", {}).items():
|
||
if sub_children:
|
||
sub_reason = f"{reason},父块未执行"
|
||
await self._create_not_executed_records(executor, child_block, sub_branch_name, sub_reason)
|
||
|
||
except Exception as e:
|
||
logger.error(f"创建未执行记录失败: {str(e)}")
|
||
# 继续执行,不影响主流程
|
||
|
||
# 遍历数组处理器
|
||
@register_handler(ProgressBlockName.ITERATE_LIST)
|
||
class IterateListBlockHandler(BlockHandler):
|
||
"""遍历数组处理器"""
|
||
|
||
async def execute(
|
||
self,
|
||
block: Dict[str, Any],
|
||
input_params: Dict[str, Any],
|
||
context: TaskContext
|
||
) -> Dict[str, Any]:
|
||
"""执行数组遍历块"""
|
||
try:
|
||
# 获取数组参数
|
||
array_data = input_params.get("list", [])
|
||
# 如果不是数组,尝试转换
|
||
if not isinstance(array_data, list):
|
||
import json
|
||
try:
|
||
if isinstance(array_data, str):
|
||
array_data = json.loads(array_data)
|
||
else:
|
||
result = {
|
||
"success": False,
|
||
"message": "提供的参数不是有效的数组"
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
except:
|
||
result = {
|
||
"success": False,
|
||
"message": "提供的参数无法解析为数组"
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
|
||
# 创建块执行器
|
||
from services.execution.block_executor import BlockExecutor
|
||
executor = BlockExecutor(context)
|
||
# 遍历数组
|
||
results = []
|
||
|
||
# 获取当前循环块的ID和名称,用于后续识别哪个break组件是作用于当前循环
|
||
current_loop_id = block.get("id")
|
||
current_loop_name = block.get("name")
|
||
|
||
logger.info(f"开始执行数组遍历块 - ID: {current_loop_id}, 名称: {current_loop_name}")
|
||
|
||
for index, item in enumerate(array_data):
|
||
# 检查是否取消
|
||
if context.is_task_canceled():
|
||
result = {
|
||
"success": False,
|
||
"message": "任务已被取消"
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
|
||
# 强制周期性释放事件循环,以便其他请求能够得到处理
|
||
if index % 10 == 0 and index > 0:
|
||
import asyncio
|
||
await asyncio.sleep(0.1) # 释放事件循环的最小时间
|
||
|
||
if context.get_variable("__RETURN__", False):
|
||
logger.info(f"检测到返回信号,提前结束重复执行")
|
||
break
|
||
# 设置循环变量,使子组件可以访问当前项和索引
|
||
context.set_variable("index", index)
|
||
context.set_variable("item", item)
|
||
context.set_block_output(block.get("name"), {"index": index, "item": item})
|
||
|
||
# 执行循环体
|
||
loop_result = await executor.execute_children(block, "default")
|
||
# 收集结果
|
||
results.append({
|
||
"index": index,
|
||
"success": loop_result.get("success", False),
|
||
"result": loop_result
|
||
})
|
||
|
||
# 如果执行失败,提前退出
|
||
if not loop_result.get("success", False):
|
||
result = {
|
||
"success": False,
|
||
"message": f"数组遍历在索引 {index} 处执行失败",
|
||
"output": {
|
||
"iterationResults": results,
|
||
"failedAt": index
|
||
}
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
|
||
# 分析是否有break信号
|
||
# 1. 先查找直接子组件是否有break组件
|
||
has_break = False
|
||
|
||
# 遍历当前循环的子组件,查找是否存在break组件及其执行情况
|
||
child_blocks = block.get("children", {}).get("default", [])
|
||
for child_block in child_blocks:
|
||
child_id = child_block.get("id")
|
||
child_name = child_block.get("name")
|
||
child_type = child_block.get("blockType")
|
||
|
||
# 直接子组件是break组件
|
||
if child_type == ProgressBlockName.BREAK:
|
||
# 检查该break组件是否执行过,通过查询其输出
|
||
break_output = context.get_block_output(child_name)
|
||
if break_output and break_output.get("breakSignal"):
|
||
logger.info(f"检测到直接子组件break信号 - 组件名称: {child_name}, ID: {child_id}")
|
||
has_break = True
|
||
break
|
||
|
||
# 子组件不是循环块(因为嵌套循环内的break应作用于内层循环)
|
||
elif child_type not in [ProgressBlockName.WHILE, ProgressBlockName.ITERATE_LIST, ProgressBlockName.REPEAT_NUM]:
|
||
# 递归检查子组件的子组件中是否有break
|
||
if "children" in child_block and child_block.get("children") and await self._check_nested_break(child_block, context):
|
||
logger.info(f"检测到嵌套break信号,来自子组件 - 组件名称: {child_name}, ID: {child_id}")
|
||
has_break = True
|
||
break
|
||
|
||
# 2. 如果检测到break信号,提前结束循环
|
||
if has_break:
|
||
logger.info(f"数组遍历检测到break信号,提前结束循环,已完成 {index+1}/{len(array_data)} 次")
|
||
await self._record_task_log(
|
||
block,
|
||
{"success": True, "message": f"第{index+1}次循环, item={item}, 检测到break信号提前结束循环"},
|
||
context
|
||
)
|
||
break
|
||
|
||
# 3. 记录正常的循环执行
|
||
await self._record_task_log(
|
||
block,
|
||
{"success": True, "message": f"第{index+1}次循环, item={item}"},
|
||
context
|
||
)
|
||
|
||
result = {
|
||
"success": True,
|
||
"message": f"数组遍历成功,共遍历了 {len(results)} 个元素",
|
||
"output": {
|
||
"iterationResults": results,
|
||
"count": len(results)
|
||
}
|
||
}
|
||
return result
|
||
except Exception as e:
|
||
result = {
|
||
"success": False,
|
||
"message": f"数组遍历执行失败: {str(e)}"
|
||
}
|
||
# 记录异常
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
|
||
async def _check_nested_break(self, block: Dict[str, Any], context: TaskContext) -> bool:
|
||
"""
|
||
递归检查嵌套组件中是否存在已执行的break组件
|
||
|
||
Args:
|
||
block: 要检查的块定义
|
||
context: 任务上下文
|
||
|
||
Returns:
|
||
bool: 是否存在已执行的break组件
|
||
"""
|
||
try:
|
||
# 获取所有可能的分支名称
|
||
branches = block.get("children", {}).keys()
|
||
|
||
# 遍历所有分支
|
||
for branch_name in branches:
|
||
branch_blocks = block.get("children", {}).get(branch_name, [])
|
||
|
||
# 遍历分支中的所有块
|
||
for child_block in branch_blocks:
|
||
child_id = child_block.get("id")
|
||
child_name = child_block.get("name")
|
||
child_type = child_block.get("blockType")
|
||
|
||
# 如果子块是循环块,则不继续向下递归检查
|
||
# 因为如果存在break,应该作用于最近的循环块而不是外层循环
|
||
if child_type in [ProgressBlockName.WHILE, ProgressBlockName.ITERATE_LIST, ProgressBlockName.REPEAT_NUM]:
|
||
logger.info(f"检测到嵌套循环块,不向下递归 - 类型: {child_type}, 名称: {child_name}")
|
||
continue
|
||
|
||
# 子块是break块
|
||
elif child_type == ProgressBlockName.BREAK:
|
||
# 检查该break组件是否执行过,通过查询其输出
|
||
break_output = context.get_block_output(child_name)
|
||
if break_output and break_output.get("breakSignal"):
|
||
logger.info(f"检测到嵌套break信号 - 组件名称: {child_name}, ID: {child_id}")
|
||
return True
|
||
|
||
# 子块是其他可能包含子组件的块(除了循环块)
|
||
elif "children" in child_block and child_block.get("children"):
|
||
# 递归检查子块中是否有break
|
||
if await self._check_nested_break(child_block, context):
|
||
return True
|
||
|
||
# 没有找到break信号
|
||
return False
|
||
except Exception as e:
|
||
logger.error(f"检查嵌套break组件失败: {str(e)}")
|
||
return False
|
||
|
||
# 延迟处理器
|
||
@register_handler(ProgressBlockName.DELAY)
|
||
class DelayBlockHandler(BlockHandler):
|
||
"""延迟处理器"""
|
||
|
||
async def execute(
|
||
self,
|
||
block: Dict[str, Any],
|
||
input_params: Dict[str, Any],
|
||
context: TaskContext
|
||
) -> Dict[str, Any]:
|
||
"""执行延迟块"""
|
||
import asyncio
|
||
|
||
try:
|
||
# 获取延迟时间参数(毫秒)
|
||
delay_time = input_params.get("timeMillis", 1000)
|
||
|
||
# 确保delay_time是数字
|
||
try:
|
||
# 转换为整数
|
||
if isinstance(delay_time, str):
|
||
delay_time = int(delay_time)
|
||
|
||
# 转换为秒
|
||
delay_sec = delay_time / 1000
|
||
|
||
# 等待
|
||
await asyncio.sleep(delay_sec)
|
||
|
||
result = {
|
||
"success": True,
|
||
"message": f"延迟 {delay_time} 毫秒完成",
|
||
"output": {
|
||
"delayTime": delay_time
|
||
}
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
except ValueError:
|
||
# 参数转换失败
|
||
result = {
|
||
"success": False,
|
||
"message": f"延迟执行失败: 无效的延迟时间参数 '{delay_time}'"
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
except Exception as e:
|
||
result = {
|
||
"success": False,
|
||
"message": f"延迟执行失败: {str(e)}"
|
||
}
|
||
# 记录异常
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
|
||
# Break处理器
|
||
@register_handler(ProgressBlockName.BREAK)
|
||
class BreakBlockHandler(BlockHandler):
|
||
"""Break处理器"""
|
||
|
||
async def execute(
|
||
self,
|
||
block: Dict[str, Any],
|
||
input_params: Dict[str, Any],
|
||
context: TaskContext
|
||
) -> Dict[str, Any]:
|
||
"""执行break块,用于跳出循环"""
|
||
try:
|
||
# 设置上下文中的break标志
|
||
#context.set_variable("__BREAK__", True)
|
||
context.set_block_output(block.get("name"), {"breakSignal": True})
|
||
result = {
|
||
"success": True,
|
||
"message": "Break执行成功,将跳出当前循环",
|
||
"output": {
|
||
"breakSignal": True
|
||
}
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
except Exception as e:
|
||
result = {
|
||
"success": False,
|
||
"message": f"Break执行失败: {str(e)}"
|
||
}
|
||
# 记录异常
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
|
||
|
||
# 返回块处理器
|
||
@register_handler(ProgressBlockName.RETURN)
|
||
class ReturnBlockHandler(BlockHandler):
|
||
"""Return处理器,用于提前返回结果"""
|
||
|
||
async def execute(
|
||
self,
|
||
block: Dict[str, Any],
|
||
input_params: Dict[str, Any],
|
||
context: TaskContext
|
||
) -> Dict[str, Any]:
|
||
"""执行return块,用于提前返回流程执行结果"""
|
||
try:
|
||
# 设置上下文中的return标志
|
||
context.set_variable("__RETURN__", True)
|
||
|
||
# 获取可能的返回数据
|
||
return_data = input_params.get("data", {})
|
||
|
||
result = {
|
||
"success": True,
|
||
"message": "Return执行成功,将提前结束流程",
|
||
"output": {
|
||
"returnSignal": True,
|
||
"returnData": return_data
|
||
}
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
except Exception as e:
|
||
result = {
|
||
"success": False,
|
||
"message": f"Return执行失败: {str(e)}"
|
||
}
|
||
# 记录异常
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
|
||
# 串行执行块处理器
|
||
@register_handler(ProgressBlockName.SERIAL_FLOW)
|
||
class SerialFlowBlockHandler(BlockHandler):
|
||
"""串行执行块处理器"""
|
||
|
||
async def execute(
|
||
self,
|
||
block: Dict[str, Any],
|
||
input_params: Dict[str, Any],
|
||
context: TaskContext
|
||
) -> Dict[str, Any]:
|
||
"""串行执行子块"""
|
||
try:
|
||
# 创建块执行器
|
||
from services.execution.block_executor import BlockExecutor
|
||
executor = BlockExecutor(context)
|
||
|
||
# 执行default分支下的所有子块
|
||
result = await executor.execute_children(block, "default")
|
||
|
||
# 检查是否成功
|
||
if not result.get("success", False):
|
||
# 记录执行结果
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
|
||
final_result = {
|
||
"success": True,
|
||
"message": "串行执行完成",
|
||
# "output": result.get("output", {})
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, final_result, context)
|
||
return final_result
|
||
except Exception as e:
|
||
result = {
|
||
"success": False,
|
||
"message": f"串行执行失败: {str(e)}"
|
||
}
|
||
# 记录异常
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
|
||
# 并行执行块处理器
|
||
@register_handler(ProgressBlockName.PARALLEL_FLOW)
|
||
class ParallelFlowBlockHandler(BlockHandler):
|
||
"""并行执行块处理器"""
|
||
|
||
async def execute(
|
||
self,
|
||
block: Dict[str, Any],
|
||
input_params: Dict[str, Any],
|
||
context: TaskContext
|
||
) -> Dict[str, Any]:
|
||
"""并行执行子块"""
|
||
import asyncio
|
||
|
||
try:
|
||
# 创建块执行器
|
||
from services.execution.block_executor import BlockExecutor
|
||
|
||
# 获取子块
|
||
children = block.get("children", {}).get("default", [])
|
||
|
||
if not children:
|
||
result = {
|
||
"success": True,
|
||
"message": "没有子块需要执行",
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
|
||
# 为每个子块创建一个执行任务
|
||
tasks = []
|
||
results = []
|
||
|
||
for child_block in children:
|
||
# 为每个子块创建一个新的执行上下文(共享同一个任务上下文)
|
||
executor = BlockExecutor(context)
|
||
|
||
# 将子块包装为一个异步任务
|
||
task = asyncio.create_task(executor.execute_block(child_block))
|
||
tasks.append(task)
|
||
|
||
# 等待所有任务完成
|
||
completed_tasks = await asyncio.gather(*tasks, return_exceptions=True)
|
||
|
||
# 处理任务结果
|
||
all_success = True
|
||
for i, result in enumerate(completed_tasks):
|
||
if isinstance(result, Exception):
|
||
results.append({
|
||
"success": False,
|
||
"message": f"子块执行异常: {str(result)}",
|
||
"index": i
|
||
})
|
||
all_success = False
|
||
else:
|
||
results.append(result)
|
||
if not result.get("success", False):
|
||
all_success = False
|
||
|
||
# 所有并行子块执行完成后,检查是否有后续处理
|
||
from services.execution.block_executor import BlockExecutor
|
||
executor = BlockExecutor(context)
|
||
|
||
# 根据执行结果处理后续分支
|
||
if all_success:
|
||
# 执行成功分支
|
||
if "success" in block.get("children", {}) and block["children"]["success"]:
|
||
logger.info(f"并行执行成功,执行success分支")
|
||
success_result = await executor.execute_children(block, "success")
|
||
if not success_result.get("success", False):
|
||
# 记录执行结果
|
||
await self._record_task_log(block, success_result, context)
|
||
return success_result
|
||
else:
|
||
# 执行失败分支
|
||
if "fail" in block.get("children", {}) and block["children"]["fail"]:
|
||
logger.info(f"并行执行部分失败,执行fail分支")
|
||
fail_result = await executor.execute_children(block, "fail")
|
||
if not fail_result.get("success", False):
|
||
# 记录执行结果
|
||
await self._record_task_log(block, fail_result, context)
|
||
return fail_result
|
||
|
||
# 执行完成分支(无论成功失败)
|
||
if "complete" in block.get("children", {}) and block["children"]["complete"]:
|
||
logger.info(f"并行执行完成,执行complete分支")
|
||
complete_result = await executor.execute_children(block, "complete")
|
||
if not complete_result.get("success", False):
|
||
# 记录执行结果
|
||
await self._record_task_log(block, complete_result, context)
|
||
return complete_result
|
||
|
||
final_result = {
|
||
"success": all_success,
|
||
"message": "并行执行完成" if all_success else "并行执行部分失败",
|
||
"output": {
|
||
# "results": results,
|
||
"allSuccess": all_success
|
||
}
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, final_result, context)
|
||
return final_result
|
||
except Exception as e:
|
||
result = {
|
||
"success": False,
|
||
"message": f"并行执行失败: {str(e)}"
|
||
}
|
||
# 记录异常
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
|
||
|
||
# 重复执行N次处理器
|
||
@register_handler(ProgressBlockName.REPEAT_NUM)
|
||
class RepeatNumBlockHandler(BlockHandler):
|
||
"""重复执行N次处理器"""
|
||
|
||
async def execute(
|
||
self,
|
||
block: Dict[str, Any],
|
||
input_params: Dict[str, Any],
|
||
context: TaskContext
|
||
) -> Dict[str, Any]:
|
||
"""重复执行子块N次"""
|
||
try:
|
||
# 获取执行次数
|
||
num = int(input_params.get("num", 1))
|
||
# 限制最大执行次数
|
||
# num = min(num, 1000)
|
||
|
||
if num <= 0 or num > 1000:
|
||
result = {
|
||
"success": False,
|
||
"message": "执行次数必须大于0且小于1000",
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
|
||
# 创建块执行器
|
||
from services.execution.block_executor import BlockExecutor
|
||
executor = BlockExecutor(context)
|
||
|
||
# 获取当前循环块的ID和名称,用于后续识别哪个break组件是作用于当前循环
|
||
current_loop_id = block.get("id")
|
||
current_loop_name = block.get("name")
|
||
|
||
logger.info(f"开始执行重复执行N次块 - ID: {current_loop_id}, 名称: {current_loop_name}, 目标次数: {num}")
|
||
|
||
# 循环执行
|
||
results = []
|
||
for i in range(num):
|
||
# 检查是否取消
|
||
if context.is_task_canceled():
|
||
result = {
|
||
"success": False,
|
||
"message": "任务已被取消"
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
|
||
# 检查是否有返回信号
|
||
if context.get_variable("__RETURN__", False):
|
||
logger.info(f"检测到返回信号,提前结束重复执行,已完成 {i}/{num} 次")
|
||
# 不需要重置返回信号,它需要向上传播
|
||
break
|
||
|
||
# 强制周期性释放事件循环,以便其他请求能够得到处理
|
||
if i % 10 == 0 and i > 0:
|
||
import asyncio
|
||
await asyncio.sleep(0.1) # 释放事件循环的最小时间
|
||
|
||
# 设置当前索引
|
||
# context.set_variable("index", i)
|
||
context.set_block_output(block.get("name"), {"index": i})
|
||
# 执行子块
|
||
result = await executor.execute_children(block, "default")
|
||
results.append({
|
||
"index": i,
|
||
"success": result.get("success", False),
|
||
"result": result
|
||
})
|
||
|
||
# 如果执行失败,提前退出
|
||
if not result.get("success", False):
|
||
failed_result = {
|
||
"success": False,
|
||
"message": f"重复执行在第 {i+1} 次时失败",
|
||
"output": {
|
||
# "results": results,
|
||
"iterations": i + 1,
|
||
"totalIterations": num,
|
||
"failedAt": i
|
||
}
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, failed_result, context)
|
||
return failed_result
|
||
|
||
# 检查是否有break信号
|
||
has_break = await self._check_for_break_signal(block, context)
|
||
if has_break:
|
||
logger.info(f"重复执行检测到break信号,提前结束循环,已完成 {i+1}/{num} 次")
|
||
break_result = {
|
||
"success": True,
|
||
"message": f"重复执行第{i+1}次检测到break信号,提前结束执行",
|
||
"output": {
|
||
"iterations": i + 1,
|
||
"totalIterations": num,
|
||
"stoppedByBreak": True
|
||
}
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, break_result, context)
|
||
|
||
# 直接跳到完成分支处理
|
||
if "complete" in block.get("children", {}) and block["children"]["complete"] and results:
|
||
# 设置迭代信息
|
||
context.set_variable("count", len(results))
|
||
context.set_variable("lastIndex", len(results) - 1)
|
||
|
||
complete_result = await executor.execute_children(block, "complete")
|
||
if not complete_result.get("success", False):
|
||
failed_complete = {
|
||
"success": False,
|
||
"message": f"完成分支执行失败: {complete_result.get('message')}",
|
||
"output": {
|
||
"iterations": len(results),
|
||
"totalIterations": num
|
||
}
|
||
}
|
||
await self._record_task_log(block, failed_complete, context)
|
||
return failed_complete
|
||
|
||
return break_result
|
||
|
||
# 执行完成分支
|
||
if "complete" in block.get("children", {}) and block["children"]["complete"] and results:
|
||
# 设置迭代信息
|
||
context.set_variable("count", len(results))
|
||
context.set_variable("lastIndex", len(results) - 1)
|
||
|
||
complete_result = await executor.execute_children(block, "complete")
|
||
if not complete_result.get("success", False):
|
||
failed_complete = {
|
||
"success": False,
|
||
"message": f"完成分支执行失败: {complete_result.get('message')}",
|
||
"output": {
|
||
"iterations": len(results),
|
||
"totalIterations": num
|
||
}
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, failed_complete, context)
|
||
return failed_complete
|
||
|
||
final_result = {
|
||
"success": True,
|
||
"message": f"重复执行成功,共执行 {len(results)} 次",
|
||
"output": {
|
||
"iterations": len(results),
|
||
"totalIterations": num
|
||
}
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, final_result, context)
|
||
return final_result
|
||
except Exception as e:
|
||
result = {
|
||
"success": False,
|
||
"message": f"重复执行N次失败: {str(e)}"
|
||
}
|
||
# 记录异常
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
|
||
async def _check_for_break_signal(self, block: Dict[str, Any], context: TaskContext) -> bool:
|
||
"""
|
||
检查是否有break信号
|
||
|
||
Args:
|
||
block: 当前块定义
|
||
context: 任务上下文
|
||
|
||
Returns:
|
||
bool: 是否有break信号
|
||
"""
|
||
try:
|
||
# 遍历当前循环的子组件,查找是否存在break组件及其执行情况
|
||
child_blocks = block.get("children", {}).get("default", [])
|
||
for child_block in child_blocks:
|
||
child_id = child_block.get("id")
|
||
child_name = child_block.get("name")
|
||
child_type = child_block.get("blockType")
|
||
|
||
# 直接子组件是break组件
|
||
if child_type == ProgressBlockName.BREAK:
|
||
# 检查该break组件是否执行过,通过查询其输出
|
||
break_output = context.get_block_output(child_name)
|
||
if break_output and break_output.get("breakSignal"):
|
||
logger.info(f"检测到直接子组件break信号 - 组件名称: {child_name}, ID: {child_id}")
|
||
return True
|
||
|
||
# 子组件不是循环块(因为嵌套循环内的break应作用于内层循环)
|
||
elif child_type not in [ProgressBlockName.WHILE, ProgressBlockName.ITERATE_LIST, ProgressBlockName.REPEAT_NUM]:
|
||
# 递归检查子组件的子组件中是否有break
|
||
if "children" in child_block and child_block.get("children") and await self._check_nested_break(child_block, context):
|
||
logger.info(f"检测到嵌套break信号,来自子组件 - 组件名称: {child_name}, ID: {child_id}")
|
||
return True
|
||
|
||
# 没有找到break信号
|
||
return False
|
||
except Exception as e:
|
||
logger.error(f"检查break信号失败: {str(e)}")
|
||
return False
|
||
|
||
async def _check_nested_break(self, block: Dict[str, Any], context: TaskContext) -> bool:
|
||
"""
|
||
递归检查嵌套组件中是否存在已执行的break组件
|
||
|
||
Args:
|
||
block: 要检查的块定义
|
||
context: 任务上下文
|
||
|
||
Returns:
|
||
bool: 是否存在已执行的break组件
|
||
"""
|
||
try:
|
||
# 获取所有可能的分支名称
|
||
branches = block.get("children", {}).keys()
|
||
|
||
# 遍历所有分支
|
||
for branch_name in branches:
|
||
branch_blocks = block.get("children", {}).get(branch_name, [])
|
||
|
||
# 遍历分支中的所有块
|
||
for child_block in branch_blocks:
|
||
child_id = child_block.get("id")
|
||
child_name = child_block.get("name")
|
||
child_type = child_block.get("blockType")
|
||
|
||
# 如果子块是循环块,则不继续向下递归检查
|
||
# 因为如果存在break,应该作用于最近的循环块而不是外层循环
|
||
if child_type in [ProgressBlockName.WHILE, ProgressBlockName.ITERATE_LIST, ProgressBlockName.REPEAT_NUM]:
|
||
logger.info(f"检测到嵌套循环块,不向下递归 - 类型: {child_type}, 名称: {child_name}")
|
||
continue
|
||
|
||
# 子块是break块
|
||
elif child_type == ProgressBlockName.BREAK:
|
||
# 检查该break组件是否执行过,通过查询其输出
|
||
break_output = context.get_block_output(child_name)
|
||
if break_output and break_output.get("breakSignal"):
|
||
logger.info(f"检测到嵌套break信号 - 组件名称: {child_name}, ID: {child_id}")
|
||
return True
|
||
|
||
# 子块是其他可能包含子组件的块(除了循环块)
|
||
elif "children" in child_block and child_block.get("children"):
|
||
# 递归检查子块中是否有break
|
||
if await self._check_nested_break(child_block, context):
|
||
return True
|
||
|
||
# 没有找到break信号
|
||
return False
|
||
except Exception as e:
|
||
logger.error(f"检查嵌套break组件失败: {str(e)}")
|
||
return False
|
||
|
||
# 抛出异常处理器
|
||
@register_handler(ProgressBlockName.THROW_EXCEPTION)
|
||
class ThrowExceptionBlockHandler(BlockHandler):
|
||
"""抛出异常处理器"""
|
||
|
||
async def execute(
|
||
self,
|
||
block: Dict[str, Any],
|
||
input_params: Dict[str, Any],
|
||
context: TaskContext
|
||
) -> Dict[str, Any]:
|
||
"""抛出异常"""
|
||
try:
|
||
# 获取异常提示文本
|
||
message = input_params.get("message", "未知异常")
|
||
|
||
# 记录日志
|
||
logger.error(f"主动抛出异常: {message}")
|
||
|
||
# 这里实际上是返回失败结果,而不是真正抛出异常
|
||
# 这样可以更好地控制任务流程
|
||
result = {
|
||
"success": False,
|
||
"message": f"主动抛出异常: {message}",
|
||
"output": {
|
||
"exceptionMessage": message
|
||
}
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
except Exception as e:
|
||
result = {
|
||
"success": False,
|
||
"message": f"抛出异常块执行失败: {str(e)}"
|
||
}
|
||
# 记录异常
|
||
await self._record_task_log(block, result, context)
|
||
return result
|