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