Class: Roast::Workflow::WorkflowExecutor

Inherits:
Object
  • Object
show all
Defined in:
lib/roast/workflow/workflow_executor.rb

Overview

Handles the execution of workflow steps, including orchestration and threading

This class now delegates all step execution to StepExecutorCoordinator, which handles type resolution and execution for all step types. The circular dependency between executors and workflow has been broken by introducing the StepRunner interface.

Defined Under Namespace

Classes: ConfigurationError, InterpolationError, StateError, StepExecutionError, StepNotFoundError, WorkflowExecutorError

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(workflow, config_hash, context_path, error_handler: nil, step_loader: nil, command_executor: nil, interpolator: nil, state_manager: nil, iteration_executor: nil, conditional_executor: nil, step_executor_coordinator: nil, phase: :steps) ⇒ WorkflowExecutor

Initialize a new WorkflowExecutor

Parameters:

  • workflow (BaseWorkflow)

    The workflow instance to execute

  • config_hash (Hash)

    The workflow configuration

  • context_path (String)

    The base path for the workflow

  • error_handler (ErrorHandler) (defaults to: nil)

    Optional custom error handler

  • step_loader (StepLoader) (defaults to: nil)

    Optional custom step loader

  • command_executor (CommandExecutor) (defaults to: nil)

    Optional custom command executor

  • interpolator (Interpolator) (defaults to: nil)

    Optional custom interpolator

  • state_manager (StateManager) (defaults to: nil)

    Optional custom state manager

  • iteration_executor (IterationExecutor) (defaults to: nil)

    Optional custom iteration executor

  • conditional_executor (ConditionalExecutor) (defaults to: nil)

    Optional custom conditional executor

  • step_executor_coordinator (StepExecutorCoordinator) (defaults to: nil)

    Optional custom step executor coordinator

  • phase (Symbol) (defaults to: :steps)

    The execution phase - determines where to load steps from Valid values:

    • :steps (default) - Load steps from the main steps directory

    • :pre_processing - Load steps from the pre_processing directory

    • :post_processing - Load steps from the post_processing directory



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/roast/workflow/workflow_executor.rb', line 51

def initialize(workflow, config_hash, context_path,
  error_handler: nil, step_loader: nil, command_executor: nil,
  interpolator: nil, state_manager: nil, iteration_executor: nil,
  conditional_executor: nil, step_executor_coordinator: nil,
  phase: :steps)
  # Create context object to reduce data clump
  @context = WorkflowContext.new(
    workflow: workflow,
    config_hash: config_hash,
    context_path: context_path,
  )

  # Dependencies with defaults
  @error_handler = error_handler || ErrorHandler.new
  @step_loader = step_loader || StepLoader.new(workflow, config_hash, context_path, phase: phase)
  @command_executor = command_executor || CommandExecutor.new(logger: @error_handler)
  @interpolator = interpolator || Interpolator.new(workflow, logger: @error_handler)
  @state_manager = state_manager || StateManager.new(workflow, logger: @error_handler, storage_type: workflow.storage_type)
  @iteration_executor = iteration_executor || IterationExecutor.new(workflow, context_path, @state_manager, config_hash)
  @conditional_executor = conditional_executor || ConditionalExecutor.new(workflow, context_path, @state_manager, self)

  # Initialize coordinator with dependencies
  base_coordinator = step_executor_coordinator || StepExecutorCoordinator.new(
    context: @context,
    dependencies: {
      workflow_executor: self,
      interpolator: @interpolator,
      command_executor: @command_executor,
      iteration_executor: @iteration_executor,
      conditional_executor: @conditional_executor,
      step_loader: @step_loader,
      state_manager: @state_manager,
      error_handler: @error_handler,
    },
  )

  # Only wrap with reporting decorator if workflow has token tracking enabled
  @step_executor_coordinator = if workflow.respond_to?(:context_manager) && workflow.context_manager
    StepExecutorWithReporting.new(base_coordinator, @context)
  else
    base_coordinator
  end
end

Instance Attribute Details

#contextObject (readonly)

Returns the value of attribute context.



29
30
31
# File 'lib/roast/workflow/workflow_executor.rb', line 29

def context
  @context
end

#state_managerObject (readonly)

Returns the value of attribute state_manager.



29
30
31
# File 'lib/roast/workflow/workflow_executor.rb', line 29

def state_manager
  @state_manager
end

#step_executor_coordinatorObject (readonly)

Returns the value of attribute step_executor_coordinator.



29
30
31
# File 'lib/roast/workflow/workflow_executor.rb', line 29

def step_executor_coordinator
  @step_executor_coordinator
end

#step_loaderObject (readonly)

Returns the value of attribute step_loader.



29
30
31
# File 'lib/roast/workflow/workflow_executor.rb', line 29

def step_loader
  @step_loader
end

Instance Method Details

#error(message) ⇒ Object



108
109
110
# File 'lib/roast/workflow/workflow_executor.rb', line 108

def error(message)
  @error_handler.log_error(message)
end

#execute_step(name, exit_on_error: true, is_last_step: nil) ⇒ Object



120
121
122
123
124
125
126
# File 'lib/roast/workflow/workflow_executor.rb', line 120

def execute_step(name, exit_on_error: true, is_last_step: nil)
  @step_executor_coordinator.execute(name, exit_on_error:, is_last_step:)
rescue StepLoader::StepNotFoundError => e
  raise StepNotFoundError.new(e.message, step_name: e.step_name, original_error: e.original_error)
rescue StepLoader::StepExecutionError => e
  raise StepExecutionError.new(e.message, step_name: e.step_name, original_error: e.original_error)
end

#execute_steps(workflow_steps) ⇒ Object



112
113
114
# File 'lib/roast/workflow/workflow_executor.rb', line 112

def execute_steps(workflow_steps)
  @step_executor_coordinator.execute_steps(workflow_steps)
end

#interpolate(text) ⇒ Object



116
117
118
# File 'lib/roast/workflow/workflow_executor.rb', line 116

def interpolate(text)
  @interpolator.interpolate(text)
end

#log_error(message) ⇒ Object

Logger interface methods for backward compatibility



96
97
98
# File 'lib/roast/workflow/workflow_executor.rb', line 96

def log_error(message)
  @error_handler.log_error(message)
end

#log_warning(message) ⇒ Object



100
101
102
# File 'lib/roast/workflow/workflow_executor.rb', line 100

def log_warning(message)
  @error_handler.log_warning(message)
end

#warn(message) ⇒ Object



104
105
106
# File 'lib/roast/workflow/workflow_executor.rb', line 104

def warn(message)
  @error_handler.log_warning(message)
end