Class: Tasker::Analysis::RuntimeGraphAnalyzer

Inherits:
Object
  • Object
show all
Defined in:
lib/tasker/analysis/runtime_graph_analyzer.rb

Overview

Runtime Graph Analyzer for Workflow Dependencies

Provides comprehensive analysis of workflow step dependencies, execution flow, and performance bottlenecks using database-backed graph analysis. Leverages existing SQL functions for optimal performance and consistency.

Examples:

Basic usage

analyzer = RuntimeGraphAnalyzer.new(task: my_task)
analysis = analyzer.analyze
puts analysis[:critical_paths][:longest_path_length]

Analyzing bottlenecks

bottlenecks = analyzer.analyze[:bottlenecks]
critical_bottlenecks = bottlenecks[:bottlenecks].select { |b| b[:severity] == 'Critical' }

Since:

  • 2.2.1

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(task:) ⇒ RuntimeGraphAnalyzer

Initialize the analyzer for a specific task

Parameters:

Raises:

  • (ArgumentError)

    if task is nil or invalid

Since:

  • 2.2.1



35
36
37
38
39
40
# File 'lib/tasker/analysis/runtime_graph_analyzer.rb', line 35

def initialize(task:)
  @task = task
  @task_id = task.task_id
  @cache = {}
  @intelligent_cache = Tasker::Telemetry::IntelligentCacheManager.new
end

Instance Attribute Details

#taskTasker::Task (readonly)

Returns The task being analyzed.

Returns:

Since:

  • 2.2.1



26
27
28
# File 'lib/tasker/analysis/runtime_graph_analyzer.rb', line 26

def task
  @task
end

#task_idInteger (readonly)

Returns The task ID for database queries.

Returns:

  • (Integer)

    The task ID for database queries

Since:

  • 2.2.1



29
30
31
# File 'lib/tasker/analysis/runtime_graph_analyzer.rb', line 29

def task_id
  @task_id
end

Instance Method Details

#analyzeHash

Perform comprehensive workflow analysis

Returns a complete analysis of the workflow including dependency graphs, critical paths, parallelism opportunities, error chains, and bottlenecks. Results are cached using IntelligentCacheManager with adaptive TTL.

Examples:

analysis = analyzer.analyze
puts "Longest path: #{analysis[:critical_paths][:longest_path_length]} steps"
puts "Critical bottlenecks: #{analysis[:bottlenecks][:critical_bottlenecks]}"

Returns:

  • (Hash)

    Complete analysis with the following keys:

    • :dependency_graph [Hash] Graph structure with nodes, edges, and adjacency lists
    • :critical_paths [Hash] Critical path analysis with longest paths and bottlenecks
    • :parallelism_opportunities [Hash] Analysis of parallel execution opportunities
    • :error_chains [Hash] Error propagation analysis and recovery strategies
    • :bottlenecks [Hash] Bottleneck identification with impact scoring

Since:

  • 2.2.1



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/tasker/analysis/runtime_graph_analyzer.rb', line 59

def analyze
  # Use intelligent caching for expensive workflow analysis
  cache_key = "tasker:analysis:runtime_graph:#{task_id}:#{task_analysis_cache_version}"

  @intelligent_cache.intelligent_fetch(cache_key, base_ttl: 90.seconds) do
    {
      dependency_graph: build_dependency_graph,
      critical_paths: analyze_critical_paths,
      parallelism_opportunities: analyze_parallelism,
      error_chains: analyze_error_chains,
      bottlenecks: identify_bottlenecks,
      generated_at: Time.current,
      task_id: task_id
    }
  end
end

#build_dependency_graphHash

Build complete dependency graph structure

Constructs a comprehensive graph representation of workflow step dependencies using database edges and SQL-based topological sorting for optimal performance.

Examples:

graph = analyzer.build_dependency_graph
root_steps = graph[:nodes].select { |n| n[:level] == 0 }
puts "Root steps: #{root_steps.map { |s| s[:name] }}"

Returns:

  • (Hash)

    Graph structure containing:

    • :nodes [Array] Graph nodes with id, name, and dependency level
    • :edges [Array] Graph edges with from/to IDs and step names
    • :adjacency_list [Hash] Forward adjacency list for graph traversal
    • :reverse_adjacency_list [Hash] Reverse adjacency list for dependency analysis
    • :dependency_levels [Hash] Step ID to dependency level mapping

Since:

  • 2.2.1



107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/tasker/analysis/runtime_graph_analyzer.rb', line 107

def build_dependency_graph
  steps = load_workflow_steps
  step_map = steps.index_by(&:workflow_step_id)
  edges = load_workflow_edges
  adjacency_lists = build_adjacency_lists(steps, edges)
  dependency_levels = calculate_dependency_levels_sql

  {
    nodes: build_graph_nodes(steps, dependency_levels),
    edges: build_graph_edges(edges, step_map),
    adjacency_list: adjacency_lists[:forward],
    reverse_adjacency_list: adjacency_lists[:reverse],
    dependency_levels: dependency_levels
  }
end

#clear_cache!void

This method returns an undefined value.

Clear all cached analysis results

Forces fresh analysis on next call to #analyze. Useful when task state has changed and you need updated analysis.

Since:

  • 2.2.1



82
83
84
85
86
87
88
89
# File 'lib/tasker/analysis/runtime_graph_analyzer.rb', line 82

def clear_cache!
  @cache.clear

  # Clear intelligent cache for this task
  cache_key = "tasker:analysis:runtime_graph:#{task_id}:#{task_analysis_cache_version}"
  @intelligent_cache.clear_performance_data(cache_key)
  Rails.cache.delete(cache_key)
end