Class: Tasker::Functions::FunctionBasedStepReadinessStatus
- Inherits:
-
FunctionWrapper
- Object
- FunctionWrapper
- Tasker::Functions::FunctionBasedStepReadinessStatus
- Defined in:
- lib/tasker/functions/function_based_step_readiness_status.rb
Overview
Function-based implementation of StepReadinessStatus Maintains the same interface as the view-based model but uses SQL functions for performance
Class Method Summary collapse
- .blocked_by_dependencies_for_task(task_id) ⇒ Object
- .blocked_by_retry_for_task(task_id) ⇒ Object
- .complete_for_task(task_id) ⇒ Object
- .failed_for_task(task_id) ⇒ Object
- .for_steps(task_id, step_ids) ⇒ Object
-
.for_task(task_id, step_ids = nil) ⇒ Object
Class methods that use SQL functions.
- .for_tasks(task_ids) ⇒ Object
- .in_progress_for_task(task_id) ⇒ Object
- .pending_for_task(task_id) ⇒ Object
- .ready_for_task(task_id) ⇒ Object
Instance Method Summary collapse
- #backoff_type ⇒ Object
- #blocking_reason ⇒ Object
-
#can_execute_now? ⇒ Boolean
Instance methods (same as original model).
- #dependency_status ⇒ Object
- #detailed_status ⇒ Object
- #effective_backoff_seconds ⇒ Object
- #retry_status ⇒ Object
- #task ⇒ Object
- #time_until_ready ⇒ Object
- #to_h ⇒ Object
-
#workflow_step ⇒ Object
Associations (lazy-loaded).
Methods inherited from FunctionWrapper
connection, convert_array_bind, from_sql_function, #readonly?, single_from_sql_function
Class Method Details
.blocked_by_dependencies_for_task(task_id) ⇒ Object
52 53 54 |
# File 'lib/tasker/functions/function_based_step_readiness_status.rb', line 52 def self.blocked_by_dependencies_for_task(task_id) for_task(task_id).reject(&:dependencies_satisfied) end |
.blocked_by_retry_for_task(task_id) ⇒ Object
56 57 58 |
# File 'lib/tasker/functions/function_based_step_readiness_status.rb', line 56 def self.blocked_by_retry_for_task(task_id) for_task(task_id).reject(&:retry_eligible) end |
.complete_for_task(task_id) ⇒ Object
72 73 74 |
# File 'lib/tasker/functions/function_based_step_readiness_status.rb', line 72 def self.complete_for_task(task_id) for_task(task_id).select { |s| s.current_state.in?(%w[complete resolved_manually]) } end |
.failed_for_task(task_id) ⇒ Object
64 65 66 |
# File 'lib/tasker/functions/function_based_step_readiness_status.rb', line 64 def self.failed_for_task(task_id) for_task(task_id).select { |s| s.current_state == 'error' } end |
.for_steps(task_id, step_ids) ⇒ Object
35 36 37 |
# File 'lib/tasker/functions/function_based_step_readiness_status.rb', line 35 def self.for_steps(task_id, step_ids) for_task(task_id, step_ids) end |
.for_task(task_id, step_ids = nil) ⇒ Object
Class methods that use SQL functions
29 30 31 32 33 |
# File 'lib/tasker/functions/function_based_step_readiness_status.rb', line 29 def self.for_task(task_id, step_ids = nil) sql = 'SELECT * FROM get_step_readiness_status($1::BIGINT, $2::BIGINT[])' binds = [task_id, step_ids] from_sql_function(sql, binds, 'StepReadinessStatus Load') end |
.for_tasks(task_ids) ⇒ Object
39 40 41 42 43 44 45 46 |
# File 'lib/tasker/functions/function_based_step_readiness_status.rb', line 39 def self.for_tasks(task_ids) return [] if task_ids.empty? # Use the batch function to get steps for multiple tasks efficiently sql = 'SELECT * FROM get_step_readiness_status_batch($1::BIGINT[])' binds = [task_ids] from_sql_function(sql, binds, 'StepReadinessStatus Batch Load') end |
.in_progress_for_task(task_id) ⇒ Object
68 69 70 |
# File 'lib/tasker/functions/function_based_step_readiness_status.rb', line 68 def self.in_progress_for_task(task_id) for_task(task_id).select { |s| s.current_state == 'in_progress' } end |
.pending_for_task(task_id) ⇒ Object
60 61 62 |
# File 'lib/tasker/functions/function_based_step_readiness_status.rb', line 60 def self.pending_for_task(task_id) for_task(task_id).select { |s| s.current_state == 'pending' } end |
.ready_for_task(task_id) ⇒ Object
48 49 50 |
# File 'lib/tasker/functions/function_based_step_readiness_status.rb', line 48 def self.ready_for_task(task_id) for_task(task_id).select(&:ready_for_execution) end |
Instance Method Details
#backoff_type ⇒ Object
117 118 119 120 121 122 123 124 125 |
# File 'lib/tasker/functions/function_based_step_readiness_status.rb', line 117 def backoff_type if backoff_request_seconds.present? && last_attempted_at.present? 'explicit_backoff' elsif last_failure_at.present? 'exponential_backoff' else 'no_backoff' end end |
#blocking_reason ⇒ Object
81 82 83 84 85 86 87 88 |
# File 'lib/tasker/functions/function_based_step_readiness_status.rb', line 81 def blocking_reason return nil if ready_for_execution return 'dependencies_not_satisfied' unless dependencies_satisfied return 'retry_not_eligible' unless retry_eligible return 'invalid_state' unless %w[pending error].include?(current_state) 'unknown' end |
#can_execute_now? ⇒ Boolean
Instance methods (same as original model)
77 78 79 |
# File 'lib/tasker/functions/function_based_step_readiness_status.rb', line 77 def can_execute_now? ready_for_execution end |
#dependency_status ⇒ Object
97 98 99 100 101 102 103 104 105 |
# File 'lib/tasker/functions/function_based_step_readiness_status.rb', line 97 def dependency_status if total_parents.zero? 'no_dependencies' elsif dependencies_satisfied 'all_satisfied' else "#{completed_parents || 0}/#{total_parents || 0}_satisfied" end end |
#detailed_status ⇒ Object
160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/tasker/functions/function_based_step_readiness_status.rb', line 160 def detailed_status { ready: ready_for_execution, current_state: current_state, dependencies: dependency_status, retry: retry_status, blocking_reason: blocking_reason, time_until_ready: time_until_ready, backoff_type: backoff_type, effective_backoff_seconds: effective_backoff_seconds } end |
#effective_backoff_seconds ⇒ Object
127 128 129 130 131 132 133 134 135 136 |
# File 'lib/tasker/functions/function_based_step_readiness_status.rb', line 127 def effective_backoff_seconds if backoff_request_seconds.present? backoff_request_seconds elsif attempts.present? && attempts.positive? # Calculate default exponential backoff (base_delay * 2^attempts, capped at 30) [2**attempts, 30].min else 0 end end |
#retry_status ⇒ Object
107 108 109 110 111 112 113 114 115 |
# File 'lib/tasker/functions/function_based_step_readiness_status.rb', line 107 def retry_status if attempts >= retry_limit 'max_retries_reached' elsif retry_eligible 'retry_eligible' else 'waiting_for_backoff' end end |
#task ⇒ Object
178 179 180 |
# File 'lib/tasker/functions/function_based_step_readiness_status.rb', line 178 def task @task ||= Tasker::Task.find(task_id) end |
#time_until_ready ⇒ Object
90 91 92 93 94 95 |
# File 'lib/tasker/functions/function_based_step_readiness_status.rb', line 90 def time_until_ready return 0 if ready_for_execution return nil unless next_retry_at [(next_retry_at - Time.current).to_i, 0].max end |
#to_h ⇒ Object
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
# File 'lib/tasker/functions/function_based_step_readiness_status.rb', line 138 def to_h { workflow_step_id: workflow_step_id, task_id: task_id, named_step_id: named_step_id, name: name, current_state: current_state, dependencies_satisfied: dependencies_satisfied, retry_eligible: retry_eligible, ready_for_execution: ready_for_execution, last_failure_at: last_failure_at, next_retry_at: next_retry_at, total_parents: total_parents, completed_parents: completed_parents, attempts: attempts, retry_limit: retry_limit, backoff_request_seconds: backoff_request_seconds, last_attempted_at: last_attempted_at, detailed_status: detailed_status } end |
#workflow_step ⇒ Object
Associations (lazy-loaded)
174 175 176 |
# File 'lib/tasker/functions/function_based_step_readiness_status.rb', line 174 def workflow_step @workflow_step ||= Tasker::WorkflowStep.find(workflow_step_id) end |