Class: CMDx::Result

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

Overview

Frozen outcome of a task execution. Provides read-only access to the task’s signal (state/status/reason/metadata/cause), the chain it belongs to, its context, and lifecycle metadata (retries, duration, rollback, deprecated). Constructed by Runtime at the end of ‘execute`.

See Also:

  • CMDx::Runtime#finalize_result
  • Signal

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(chain, task, signal, **options) ⇒ Result

Returns a new instance of Result.

Parameters:

  • chain (Chain)

    the chain this result belongs to

  • task (Task)

    the executed task instance

  • signal (Signal)

    the final signal from the task’s lifecycle

  • options (Hash{Symbol => Object})

    frozen execution metadata

Options Hash (**options):

  • :tid (String)
  • :strict (Boolean)
  • :deprecated (Boolean)
  • :rolled_back (Boolean)
  • :retries (Integer)
  • :duration (Float)

    milliseconds



33
34
35
36
37
38
# File 'lib/cmdx/result.rb', line 33

def initialize(chain, task, signal, **options)
  @chain   = chain
  @task    = task
  @signal  = signal
  @options = options.freeze
end

Instance Attribute Details

#chainObject (readonly)

Returns the value of attribute chain.



21
22
23
# File 'lib/cmdx/result.rb', line 21

def chain
  @chain
end

Instance Method Details

#as_jsonHash{Symbol => Object}

JSON-friendly hash view. Aliases the memoized #to_h for conventional ‘as_json` callers (e.g. Rails).

Returns:

  • (Hash{Symbol => Object})


314
315
316
# File 'lib/cmdx/result.rb', line 314

def as_json(*)
  to_h
end

#backtraceArray<String>?

The backtrace captured by ‘fail!` / `throw!` for Fault propagation. `nil` when this result is not a failure or the failure didn’t capture a backtrace.

Returns:

  • (Array<String>, nil)


237
238
239
# File 'lib/cmdx/result.rb', line 237

def backtrace
  @signal.backtrace
end

#causeException?

Returns:

  • (Exception, nil)


183
184
185
# File 'lib/cmdx/result.rb', line 183

def cause
  @signal.cause
end

#caused_failureResult?

The originating failed result at the bottom of the propagation chain. Walks ‘origin` recursively. `self` when this result is the originator; `nil` when not failed.

Returns:



206
207
208
209
210
# File 'lib/cmdx/result.rb', line 206

def caused_failure
  return unless failed?

  @caused_failure ||= origin ? origin.caused_failure : self
end

#caused_failure?Boolean

Returns true when this result originated the failure chain.

Returns:

  • (Boolean)

    true when this result originated the failure chain



213
214
215
# File 'lib/cmdx/result.rb', line 213

def caused_failure?
  failed? && origin.nil?
end

#cidString

Returns uuid_v7 identifier for the chain this result belongs to.

Returns:

  • (String)

    uuid_v7 identifier for the chain this result belongs to



63
64
65
# File 'lib/cmdx/result.rb', line 63

def cid
  chain.id
end

#complete?Boolean

Returns:

  • (Boolean)


94
95
96
# File 'lib/cmdx/result.rb', line 94

def complete?
  @signal.complete?
end

#contextContext Also known as: ctx

Returns frozen after the root task’s teardown.

Returns:

  • (Context)

    frozen after the root task’s teardown



78
79
80
# File 'lib/cmdx/result.rb', line 78

def context
  @task.context
end

#deconstructArray<Array(Symbol, Object)>

Pattern-matching support for ‘case result in […]`.

Returns:

  • (Array<Array(Symbol, Object)>)


361
362
363
# File 'lib/cmdx/result.rb', line 361

def deconstruct
  to_h.to_a
end

#deconstruct_keys(keys) ⇒ Hash{Symbol => Object}

Pattern-matching support for ‘case result in …`.

Parameters:

  • keys (Array<Symbol>, nil)

    restrict the returned hash to these keys

Returns:

  • (Hash{Symbol => Object})


354
355
356
# File 'lib/cmdx/result.rb', line 354

def deconstruct_keys(keys)
  keys.nil? ? to_h : to_h.slice(*keys)
end

#deprecated?Boolean

Returns true when the task class is marked deprecated.

Returns:

  • (Boolean)

    true when the task class is marked deprecated



257
258
259
# File 'lib/cmdx/result.rb', line 257

def deprecated?
  !!@options[:deprecated]
end

#durationFloat?

Returns lifecycle duration in milliseconds.

Returns:

  • (Float, nil)

    lifecycle duration in milliseconds



267
268
269
# File 'lib/cmdx/result.rb', line 267

def duration
  @options[:duration]
end

#errorException, ...

Convenience accessor that returns the underlying exception when the failure was produced by a rescued exception, otherwise the human ‘reason`. `nil` for non-failed results. Useful for telemetry adapters (Sentry, Bugsnag, …) that branch on whether an exception is available without forcing every subscriber to repeat the `cause || reason` dance.

Returns:

  • (Exception, String, nil)


195
196
197
198
199
# File 'lib/cmdx/result.rb', line 195

def error
  return unless failed?

  cause || reason
end

#errorsErrors

Returns frozen by Runtime teardown.

Returns:

  • (Errors)

    frozen by Runtime teardown



84
85
86
# File 'lib/cmdx/result.rb', line 84

def errors
  @task.errors
end

#failed?Boolean

Returns:

  • (Boolean)


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

def failed?
  @signal.failed?
end

#indexInteger?

Returns this result’s position in the chain.

Returns:

  • (Integer, nil)

    this result’s position in the chain



68
69
70
# File 'lib/cmdx/result.rb', line 68

def index
  @chain.index(self)
end

#interrupted?Boolean

Returns:

  • (Boolean)


99
100
101
# File 'lib/cmdx/result.rb', line 99

def interrupted?
  @signal.interrupted?
end

#ko?Boolean

Returns:

  • (Boolean)


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

def ko?
  @signal.ko?
end

#metadataHash{Symbol => Object}

Returns frozen empty hash when none provided.

Returns:

  • (Hash{Symbol => Object})

    frozen empty hash when none provided



169
170
171
# File 'lib/cmdx/result.rb', line 169

def 
  @signal.
end

#ok?Boolean

Returns:

  • (Boolean)


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

def ok?
  @signal.ok?
end

#on(*keys) {|result| ... } ⇒ Result

Dispatches the block when any of ‘keys` matches a truthy predicate on this result. Returns `self` for chaining.

Examples:

result
  .on(:success) { |r| deliver(r.context) }
  .on(:failed)  { |r| alert(r.reason) }

Parameters:

  • keys (Array<Symbol, String>)

    any of the predicate bases: ‘complete`, `interrupted`, `success`, `skipped`, `failed`, `ok`, `ko`

Yield Parameters:

  • result (Result)

    this result

Returns:

  • (Result)

    self for chaining

Raises:

  • (ArgumentError)

    when no block is given or a key is unknown



146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/cmdx/result.rb', line 146

def on(*keys)
  raise ArgumentError, "Result#on requires a block" unless block_given?

  yield(self) if keys.any? do |k|
    unless EVENTS.include?(k.to_sym)
      raise ArgumentError, <<~MSG.chomp
        unknown Result#on event #{k.inspect}, must be one of #{EVENTS.to_a.inspect}.
        See https://drexed.github.io/cmdx/outcomes/result/#predicate-dispatch
      MSG
    end

    public_send(:"#{k}?")
  end

  self
end

#originResult?

The upstream failed result this one was echoed from (via ‘Task#throw!` or a rescued Fault inside `work`). `nil` when this is a locally originated failure or the result didn’t fail.

Returns:



178
179
180
# File 'lib/cmdx/result.rb', line 178

def origin
  @signal.origin
end

#reasonString?

Returns:

  • (String, nil)


164
165
166
# File 'lib/cmdx/result.rb', line 164

def reason
  @signal.reason
end

#retried?Boolean

Returns:

  • (Boolean)


247
248
249
# File 'lib/cmdx/result.rb', line 247

def retried?
  retries.positive?
end

#retriesInteger

Returns:

  • (Integer)


242
243
244
# File 'lib/cmdx/result.rb', line 242

def retries
  @options[:retries] || 0
end

#rolled_back?Boolean

Returns true when a failing task’s ‘rollback` ran.

Returns:

  • (Boolean)

    true when a failing task’s ‘rollback` ran



262
263
264
# File 'lib/cmdx/result.rb', line 262

def rolled_back?
  !!@options[:rolled_back]
end

#root?Boolean

Returns true when this result is the root of the chain.

Returns:

  • (Boolean)

    true when this result is the root of the chain



73
74
75
# File 'lib/cmdx/result.rb', line 73

def root?
  !!@options[:root]
end

#skipped?Boolean

Returns:

  • (Boolean)


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

def skipped?
  @signal.skipped?
end

#stateString

Returns one of Signal::STATES.

Returns:



89
90
91
# File 'lib/cmdx/result.rb', line 89

def state
  @signal.state
end

#statusString

Returns one of Signal::STATUSES.

Returns:



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

def status
  @signal.status
end

#strict?Boolean

Returns true when produced via ‘execute!`.

Returns:

  • (Boolean)

    true when produced via ‘execute!`



252
253
254
# File 'lib/cmdx/result.rb', line 252

def strict?
  !!@options[:strict]
end

#success?Boolean

Returns:

  • (Boolean)


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

def success?
  @signal.success?
end

#tagsArray<Symbol, String>

Returns:

  • (Array<Symbol, String>)


272
273
274
# File 'lib/cmdx/result.rb', line 272

def tags
  task.settings.tags
end

#taskClass<Task>

Returns the task class that ran.

Returns:

  • (Class<Task>)

    the task class that ran



46
47
48
# File 'lib/cmdx/result.rb', line 46

def task
  @task.class
end

#threw_failureResult?

The nearest upstream failed result. ‘self` when this result is the originator; `nil` when not failed.

Returns:



221
222
223
224
225
# File 'lib/cmdx/result.rb', line 221

def threw_failure
  return unless failed?

  origin || self
end

#thrown_failure?Boolean

Returns true when this result re-threw an upstream failure.

Returns:

  • (Boolean)

    true when this result re-threw an upstream failure



228
229
230
# File 'lib/cmdx/result.rb', line 228

def thrown_failure?
  failed? && !origin.nil?
end

#tidString

Returns uuid_v7 identifier for this execution.

Returns:

  • (String)

    uuid_v7 identifier for this execution



41
42
43
# File 'lib/cmdx/result.rb', line 41

def tid
  @options[:tid]
end

#to_hHash{Symbol => Object}

Returns memoized serialization. Includes ‘:cause`, `:origin`, `:threw_failure`, `:caused_failure`, `:rolled_back` on failure.

Returns:

  • (Hash{Symbol => Object})

    memoized serialization. Includes ‘:cause`, `:origin`, `:threw_failure`, `:caused_failure`, `:rolled_back` on failure.



279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
# File 'lib/cmdx/result.rb', line 279

def to_h
  @to_h ||= {
    xid:,
    cid:,
    index:,
    root: root?,
    type:,
    task:,
    tid:,
    context:,
    state:,
    status:,
    reason:,
    metadata:,
    strict: strict?,
    deprecated: deprecated?,
    retried: retried?,
    retries:,
    duration:,
    tags:
  }.tap do |hash|
    if failed?
      hash[:cause] = cause
      hash[:origin] = hash_for_failure(:origin)
      hash[:threw_failure] = hash_for_failure(:threw_failure)
      hash[:caused_failure] = hash_for_failure(:caused_failure)
      hash[:rolled_back] = rolled_back?
    end
  end
end

#to_json(*args) ⇒ String

Serializes the result to a JSON string. Non-primitive entries (the ‘:task` Class, `:cause` Exception) emit via their stdlib `to_json` defaults; `:context` delegates to Context#to_json.

Parameters:

  • args (Array)

    forwarded to ‘Hash#to_json`

Returns:

  • (String)


324
325
326
# File 'lib/cmdx/result.rb', line 324

def to_json(*args)
  to_h.to_json(*args)
end

#to_sString

Returns space-separated ‘key=value.inspect` pairs; failure references render as `<TaskClass uuid>`.

Returns:

  • (String)

    space-separated ‘key=value.inspect` pairs; failure references render as `<TaskClass uuid>`.



330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
# File 'lib/cmdx/result.rb', line 330

def to_s
  @to_s ||= begin
    buf = String.new(capacity: 256)

    to_h.each_with_object(buf) do |(k, v), buf|
      buf << " " unless buf.empty?

      ks = k.name

      if v.nil?
        buf << ks << "=nil"
      elsif ks == "origin" || ks.end_with?("_failure")
        buf << ks << "=<" << v[:task].to_s << " " << v[:tid] << ">"
      else
        buf << ks << "=" << v.inspect
      end
    end
  end
end

#typeString

Returns ‘“Task”` or `“Workflow”`.

Returns:

  • (String)

    ‘“Task”` or `“Workflow”`



51
52
53
# File 'lib/cmdx/result.rb', line 51

def type
  task.type
end

#xidString?

Returns resolved correlation id from this result’s chain (produced by the configured ‘correlation_id` callable when the root chain was acquired).

Returns:

  • (String, nil)

    resolved correlation id from this result’s chain (produced by the configured ‘correlation_id` callable when the root chain was acquired)



58
59
60
# File 'lib/cmdx/result.rb', line 58

def xid
  chain.xid
end