Class: CMDx::Signal

Inherits:
Object
  • Object
show all
Defined in:
lib/cmdx/signal.rb

Overview

Internal halt token thrown by ‘success!`, `skip!`, `fail!`, and `throw!` from inside a Task’s ‘work`. Runtime catches `Signal::TAG` and converts the payload into a Result. Not meant to be raised directly by user code.

See Also:

  • Runtime#perform_work
  • Task#success!
  • Task#fail!

Constant Summary collapse

TAG =

‘catch`/`throw` tag used by Runtime to intercept signal payloads.

:cmdx_signal
STATES =

All valid execution lifecycle states.

[
  COMPLETE    = "complete",
  INTERRUPTED = "interrupted"
].freeze
STATUSES =

All valid outcome statuses.

[
  SUCCESS = "success",
  SKIPPED = "skipped",
  FAILED  = "failed"
].freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(state, status, **options) ⇒ Signal

Returns a new instance of Signal.

Parameters:

  • state (String)

    one of STATES

  • status (String)

    one of STATUSES

  • options (Hash{Symbol => Object})

    frozen metadata payload

Options Hash (**options):

  • :reason (String)
  • :metadata (Hash)
  • :cause (Exception)
  • :origin (Result)
  • :backtrace (Array<Thread::Backtrace::Location>)


97
98
99
100
101
# File 'lib/cmdx/signal.rb', line 97

def initialize(state, status, **options)
  @state   = state
  @status  = status
  @options = options.freeze
end

Instance Attribute Details

#stateObject (readonly)

Returns the value of attribute state.



87
88
89
# File 'lib/cmdx/signal.rb', line 87

def state
  @state
end

#statusObject (readonly)

Returns the value of attribute status.



87
88
89
# File 'lib/cmdx/signal.rb', line 87

def status
  @status
end

Class Method Details

.echoed(other, **options) ⇒ Signal

Mirrors another Signal/Result’s state + status with fresh options. Used by Runtime to propagate a nested ‘Fault`’s outcome.

Parameters:

  • other (Signal, Result)

    source to mirror state/status/reason from

  • options (Hash{Symbol => Object})

    overrides: ‘:metadata`, `:cause`, `:backtrace`, `:origin`

Options Hash (**options):

  • :metadata (Hash{Symbol => Object})

    merged onto the task metadata payload

  • :cause (Exception)

    upstream exception when mirroring failures

  • :backtrace (Array<Thread::Backtrace::Location>)

    captured frames

  • :origin (Result)

    peer result this signal echoes (set automatically for Results)

Returns:

  • (Signal)

    new instance mirroring ‘other`

Raises:

  • (ArgumentError)

    when ‘other` is neither a Signal nor a Result



78
79
80
81
82
83
# File 'lib/cmdx/signal.rb', line 78

def echoed(other, **options)
  raise ArgumentError, "must be a Result or Signal" unless other.is_a?(Result) || other.is_a?(Signal)

  options[:origin] = other if other.is_a?(Result) && !options.key?(:origin)
  new(other.state, other.status, **options, reason: other.reason)
end

.failed(reason = nil, **options) ⇒ Signal

Builds a failed signal (state ‘interrupted`, status `failed`).

Parameters:

  • reason (String, nil) (defaults to: nil)

    optional human-readable reason

  • options (Hash{Symbol => Object})

    optional ‘:metadata`, `:cause`, `:backtrace`

Options Hash (**options):

  • :metadata (Hash{Symbol => Object})

    merged onto the task metadata payload

  • :cause (Exception)

    upstream exception when mirroring failures

  • :backtrace (Array<Thread::Backtrace::Location>)

    captured frames

Returns:

  • (Signal)

    new instance with frozen options



62
63
64
# File 'lib/cmdx/signal.rb', line 62

def failed(reason = nil, **options)
  new(INTERRUPTED, FAILED, **options, reason:)
end

.skipped(reason = nil, **options) ⇒ Signal

Builds a skipped signal (state ‘interrupted`, status `skipped`).

Parameters:

  • reason (String, nil) (defaults to: nil)

    optional human-readable reason

  • options (Hash{Symbol => Object})

    optional ‘:metadata`, `:cause`, `:backtrace`

Options Hash (**options):

  • :metadata (Hash{Symbol => Object})

    merged onto the task metadata payload

  • :cause (Exception)

    upstream exception when mirroring failures

  • :backtrace (Array<Thread::Backtrace::Location>)

    captured frames

Returns:

  • (Signal)

    new instance with frozen options



50
51
52
# File 'lib/cmdx/signal.rb', line 50

def skipped(reason = nil, **options)
  new(INTERRUPTED, SKIPPED, **options, reason:)
end

.success(reason = nil, **options) ⇒ Signal

Builds a successful signal (state ‘complete`, status `success`).

Parameters:

  • reason (String, nil) (defaults to: nil)

    optional human-readable reason

  • options (Hash{Symbol => Object})

    optional ‘:metadata`, `:cause`, `:backtrace`

Options Hash (**options):

  • :metadata (Hash{Symbol => Object})

    merged onto the task metadata payload

  • :cause (Exception)

    upstream exception when mirroring failures

  • :backtrace (Array<Thread::Backtrace::Location>)

    captured frames

Returns:

  • (Signal)

    new instance with frozen options



38
39
40
# File 'lib/cmdx/signal.rb', line 38

def success(reason = nil, **options)
  new(COMPLETE, SUCCESS, **options, reason:)
end

Instance Method Details

#backtraceArray<Thread::Backtrace::Location>?

Returns caller locations captured by ‘fail!` / `throw!` for Fault backtraces.

Returns:

  • (Array<Thread::Backtrace::Location>, nil)

    caller locations captured by ‘fail!` / `throw!` for Fault backtraces



160
161
162
# File 'lib/cmdx/signal.rb', line 160

def backtrace
  @options[:backtrace]
end

#causeException?

Returns underlying exception when a rescue produced this signal.

Returns:

  • (Exception, nil)

    underlying exception when a rescue produced this signal



149
150
151
# File 'lib/cmdx/signal.rb', line 149

def cause
  @options[:cause]
end

#complete?Boolean

Returns true when the task ran to completion without interruption.

Returns:

  • (Boolean)

    true when the task ran to completion without interruption



104
105
106
# File 'lib/cmdx/signal.rb', line 104

def complete?
  state == COMPLETE
end

#failed?Boolean

Returns:

  • (Boolean)


124
125
126
# File 'lib/cmdx/signal.rb', line 124

def failed?
  status == FAILED
end

#interrupted?Boolean

Returns true when skip/fail interrupted the task.

Returns:

  • (Boolean)

    true when skip/fail interrupted the task



109
110
111
# File 'lib/cmdx/signal.rb', line 109

def interrupted?
  state == INTERRUPTED
end

#ko?Boolean

Returns true for skipped or failed (anything but success).

Returns:

  • (Boolean)

    true for skipped or failed (anything but success)



134
135
136
# File 'lib/cmdx/signal.rb', line 134

def ko?
  !success?
end

#metadataHash{Symbol => Object}

Returns frozen-empty hash when none was provided.

Returns:

  • (Hash{Symbol => Object})

    frozen-empty hash when none was provided



144
145
146
# File 'lib/cmdx/signal.rb', line 144

def 
  @options[:metadata] || EMPTY_HASH
end

#ok?Boolean

Returns true for success or skipped (anything but failed).

Returns:

  • (Boolean)

    true for success or skipped (anything but failed)



129
130
131
# File 'lib/cmdx/signal.rb', line 129

def ok?
  !failed?
end

#originResult?

Returns upstream result this signal was echoed from, when any.

Returns:

  • (Result, nil)

    upstream result this signal was echoed from, when any



154
155
156
# File 'lib/cmdx/signal.rb', line 154

def origin
  @options[:origin]
end

#reasonString?

Returns human-readable explanation supplied by the caller.

Returns:

  • (String, nil)

    human-readable explanation supplied by the caller



139
140
141
# File 'lib/cmdx/signal.rb', line 139

def reason
  @options[:reason]
end

#skipped?Boolean

Returns:

  • (Boolean)


119
120
121
# File 'lib/cmdx/signal.rb', line 119

def skipped?
  status == SKIPPED
end

#success?Boolean

Returns:

  • (Boolean)


114
115
116
# File 'lib/cmdx/signal.rb', line 114

def success?
  status == SUCCESS
end