Class: Smith::Workflow::ExecutionFrame

Inherits:
Object
  • Object
show all
Defined in:
lib/smith/workflow/execution_frame.rb

Overview

Absorbs the five-flag bookkeeping pattern (claimed, result_obtained, recorded, intentional_retry, finalize_succeeded) duplicated across host Execution wrappers. The host yields its per-attempt work in, records lifecycle milestones via mark_*! setters, and the frame’s ensure invokes on_clear / always_ensure based on the canonical decision: claimed && (finalize_succeeded || (intentional_retry && recorded) || !result_obtained).

OrderingError and AlreadyRun inherit from Smith::Error (NOT Smith::WorkflowError) so host ‘rescue Smith::WorkflowError` blocks cannot silently downgrade ordering bugs to handler-error states.

Defined Under Namespace

Classes: AlreadyRun, OrderingError

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(workflow: nil, on_clear: nil, always_ensure: nil, logger: nil) ⇒ ExecutionFrame

Returns a new instance of ExecutionFrame.



26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/smith/workflow/execution_frame.rb', line 26

def initialize(workflow: nil, on_clear: nil, always_ensure: nil, logger: nil)
  @workflow = workflow
  @on_clear = on_clear
  @always_ensure = always_ensure
  @logger = logger
  @claimed = false
  @claimed_set = false
  @result_obtained = false
  @recorded = false
  @intentional_retry = false
  @finalize_succeeded = false
  @run_invoked = false
  @finished = false
end

Class Method Details

.run(workflow: nil, on_clear: nil, always_ensure: nil, logger: nil) ⇒ Object



22
23
24
# File 'lib/smith/workflow/execution_frame.rb', line 22

def self.run(workflow: nil, on_clear: nil, always_ensure: nil, logger: nil)
  new(workflow: workflow, on_clear: on_clear, always_ensure: always_ensure, logger: logger).run { |frame| yield frame }
end

Instance Method Details

#claimed?Boolean

Returns:

  • (Boolean)


87
88
89
# File 'lib/smith/workflow/execution_frame.rb', line 87

def claimed?
  @claimed == true
end

#finalize_succeeded?Boolean

Returns:

  • (Boolean)


103
104
105
# File 'lib/smith/workflow/execution_frame.rb', line 103

def finalize_succeeded?
  @finalize_succeeded
end

#finish!Object



111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/smith/workflow/execution_frame.rb', line 111

def finish!
  return false if @finished

  @finished = true
  cleared = false

  if should_clear?
    cleared = invoke_on_clear
  end

  invoke_always_ensure if claimed?

  cleared
end

#intentional_retry?Boolean

Returns:

  • (Boolean)


99
100
101
# File 'lib/smith/workflow/execution_frame.rb', line 99

def intentional_retry?
  @intentional_retry
end

#mark_claimed!(value = true) ⇒ Object



51
52
53
54
55
56
57
58
59
# File 'lib/smith/workflow/execution_frame.rb', line 51

def mark_claimed!(value = true)
  if @claimed_set && @claimed != value
    raise OrderingError, "mark_claimed! called twice with conflicting values (#{@claimed.inspect} then #{value.inspect})"
  end

  @claimed = value
  @claimed_set = true
  value
end

#mark_finalize_succeeded!Object

Raises:



81
82
83
84
85
# File 'lib/smith/workflow/execution_frame.rb', line 81

def mark_finalize_succeeded!
  raise OrderingError, "mark_finalize_succeeded! requires prior mark_recorded!" unless @recorded

  @finalize_succeeded = true
end

#mark_intentional_retry!(value = true) ⇒ Object



73
74
75
76
77
78
79
# File 'lib/smith/workflow/execution_frame.rb', line 73

def mark_intentional_retry!(value = true)
  if @claimed_set && @claimed == false
    raise OrderingError, "mark_intentional_retry! invalid after mark_claimed!(false)"
  end

  @intentional_retry = value
end

#mark_recorded!Object

Raises:



67
68
69
70
71
# File 'lib/smith/workflow/execution_frame.rb', line 67

def mark_recorded!
  raise OrderingError, "mark_recorded! requires prior mark_result_obtained!" unless @result_obtained

  @recorded = true
end

#mark_result_obtained!Object

Raises:



61
62
63
64
65
# File 'lib/smith/workflow/execution_frame.rb', line 61

def mark_result_obtained!
  raise OrderingError, "mark_result_obtained! requires prior mark_claimed!(true)" unless @claimed == true

  @result_obtained = true
end

#recorded?Boolean

Returns:

  • (Boolean)


95
96
97
# File 'lib/smith/workflow/execution_frame.rb', line 95

def recorded?
  @recorded
end

#result_obtained?Boolean

Returns:

  • (Boolean)


91
92
93
# File 'lib/smith/workflow/execution_frame.rb', line 91

def result_obtained?
  @result_obtained
end

#runObject



41
42
43
44
45
46
47
48
49
# File 'lib/smith/workflow/execution_frame.rb', line 41

def run
  raise AlreadyRun, "ExecutionFrame already run" if @run_invoked

  @run_invoked = true
  result = yield(self)
  result
ensure
  finish!
end

#should_clear?Boolean

Returns:

  • (Boolean)


107
108
109
# File 'lib/smith/workflow/execution_frame.rb', line 107

def should_clear?
  claimed? && (@finalize_succeeded || (@intentional_retry && @recorded) || !@result_obtained)
end