Module: GenevaDrive::FlowControl

Included in:
Workflow
Defined in:
lib/geneva_drive/flow_control.rb

Overview

Module providing flow control methods for use within workflow steps. These methods use throw/catch to interrupt step execution and signal the executor how to proceed.

When called outside of a step execution context (e.g., from a controller), pause! and skip! will directly modify the workflow state.

Examples:

Using flow control in a step

step :process_payment do
  result = PaymentGateway.charge(hero)
  cancel! if result.declined?
  skip! if result.already_processed?
end

External flow control

workflow = MyWorkflow.find(id)
workflow.pause!  # Pauses workflow from outside a step

Instance Method Summary collapse

Instance Method Details

#cancel!void

This method returns an undefined value.

Cancels the workflow immediately.

When called inside a step (workflow state is 'performing'): interrupts execution via throw/catch. When called outside a step (workflow state is 'ready' or 'paused'): directly cancels the workflow.

Raises:

  • (InvalidStateError)

    if called on a non-ready/non-paused/non-performing workflow



103
104
105
106
107
108
109
110
# File 'lib/geneva_drive/flow_control.rb', line 103

def cancel!
  if state == "performing"
    logger.info("Flow control: cancel! called from step")
    throw :flow_control, GenevaDrive::FlowControlSignal.new(:cancel)
  else
    external_cancel!
  end
end

#finished!void

This method returns an undefined value.

Marks the workflow as finished immediately. Useful for early termination when no further steps are needed.

Raises:

  • (UncaughtThrowError)

    if called outside of step execution context



166
167
168
169
# File 'lib/geneva_drive/flow_control.rb', line 166

def finished!
  logger.info("Flow control: finished! called from step")
  throw :flow_control, GenevaDrive::FlowControlSignal.new(:finished)
end

#pause!void

This method returns an undefined value.

Pauses the workflow for manual intervention.

When called inside a step (workflow state is 'performing'): interrupts execution via throw/catch. When called outside a step (workflow state is 'ready'): directly pauses the workflow.

Can be resumed later with Workflow#resume!.

Raises:



121
122
123
124
125
126
127
128
# File 'lib/geneva_drive/flow_control.rb', line 121

def pause!
  if state == "performing"
    logger.info("Flow control: pause! called from step")
    throw :flow_control, GenevaDrive::FlowControlSignal.new(:pause)
  else
    external_pause!
  end
end

#reattempt!(wait: nil) ⇒ void

This method returns an undefined value.

Reschedules the current step for another attempt. Useful for handling temporary failures or rate limiting.

Examples:

Retry after rate limit

reattempt!(wait: 5.minutes)

Parameters:

  • wait (ActiveSupport::Duration, nil) (defaults to: nil)

    optional delay before retry

Raises:

  • (UncaughtThrowError)

    if called outside of step execution context



139
140
141
142
143
# File 'lib/geneva_drive/flow_control.rb', line 139

def reattempt!(wait: nil)
  wait_msg = wait ? " with wait #{wait.inspect}" : ""
  logger.info("Flow control: reattempt! called from step#{wait_msg}")
  throw :flow_control, GenevaDrive::FlowControlSignal.new(:reattempt, wait: wait)
end

#skip!void

This method returns an undefined value.

Skips the current step and proceeds to the next one.

When called inside a step (workflow state is 'performing'): interrupts execution via throw/catch. When called outside a step (workflow state is 'ready'): directly skips current step.

Raises:



152
153
154
155
156
157
158
159
# File 'lib/geneva_drive/flow_control.rb', line 152

def skip!
  if state == "performing"
    logger.info("Flow control: skip! called from step")
    throw :flow_control, GenevaDrive::FlowControlSignal.new(:skip)
  else
    external_skip!
  end
end