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