From 18ec31738a7368192d54698efd71ff512ed3f844 Mon Sep 17 00:00:00 2001 From: Masonmason Date: Wed, 23 Jul 2025 22:43:42 +0800 Subject: [PATCH] fix: Ensure result callback is always set on pipeline regardless of result handler - Remove dependency on result_handler for setting pipeline result callback - Always call result_callback when handle_result is triggered - This fixes the issue where GUI callbacks weren't being called because output type 'display' wasn't supported, causing result_handler to be None - Add more debug output to trace callback flow --- .../core/functions/workflow_orchestrator.py | 41 +++++++++++-------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/cluster4npu_ui/core/functions/workflow_orchestrator.py b/cluster4npu_ui/core/functions/workflow_orchestrator.py index 3175fc3..abc9da4 100644 --- a/cluster4npu_ui/core/functions/workflow_orchestrator.py +++ b/cluster4npu_ui/core/functions/workflow_orchestrator.py @@ -58,9 +58,10 @@ class WorkflowOrchestrator: # Set the pipeline's put_data method as the callback self.data_source.set_data_callback(self.pipeline.put_data) - # Set the result callback on the pipeline - if self.result_handler: - self.pipeline.set_result_callback(self.handle_result) + # Set the result callback on the pipeline - always set this regardless of result_handler + # The handle_result method will decide what to do with the results + self.pipeline.set_result_callback(self.handle_result) + print(f"🔍 ORCHESTRATOR DEBUG: Set result callback on pipeline") # Start the pipeline self.pipeline.initialize() @@ -162,26 +163,32 @@ class WorkflowOrchestrator: print(f"🔍 ORCHESTRATOR DEBUG: handle_result called with: {result_data}") print(f"🔍 ORCHESTRATOR DEBUG: result_callback is: {self.result_callback}") - if self.result_handler: - try: - # Convert PipelineData to a dictionary for serialization - result_dict = { - "pipeline_id": result_data.pipeline_id, - "timestamp": result_data.timestamp, - "metadata": result_data.metadata, - "stage_results": result_data.stage_results - } + try: + # Convert PipelineData to a dictionary for serialization + result_dict = { + "pipeline_id": result_data.pipeline_id, + "timestamp": result_data.timestamp, + "metadata": result_data.metadata, + "stage_results": result_data.stage_results + } + + # Save to file if result handler exists + if self.result_handler: self.result_handler.save_result( result_dict, self.pipeline.pipeline_name, format=self.output_config.get('format', 'json').lower() ) + + # Always call the result callback if set (for GUI updates) + if self.result_callback: + print(f"🔍 ORCHESTRATOR DEBUG: Calling result_callback with: {result_dict}") + self.result_callback(result_dict) + else: + print(f"🔍 ORCHESTRATOR DEBUG: No result_callback set in orchestrator!") - # Also call the result callback if set - if self.result_callback: - self.result_callback(result_dict) - except Exception as e: - print(f"❌ Error handling result: {e}") + except Exception as e: + print(f"❌ Error handling result: {e}") def _parse_resolution(self, resolution_str: Optional[str]) -> Optional[tuple[int, int]]: """