cmdx 1.0.1 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.cursor/prompts/docs.md +9 -0
- data/.cursor/prompts/rspec.md +21 -0
- data/.cursor/prompts/yardoc.md +13 -0
- data/.rubocop.yml +2 -0
- data/CHANGELOG.md +29 -3
- data/README.md +2 -1
- data/docs/ai_prompts.md +269 -195
- data/docs/basics/call.md +126 -60
- data/docs/basics/chain.md +190 -160
- data/docs/basics/context.md +242 -154
- data/docs/basics/setup.md +302 -32
- data/docs/callbacks.md +382 -119
- data/docs/configuration.md +211 -49
- data/docs/deprecation.md +245 -0
- data/docs/getting_started.md +161 -39
- data/docs/internationalization.md +590 -70
- data/docs/interruptions/exceptions.md +135 -118
- data/docs/interruptions/faults.md +152 -127
- data/docs/interruptions/halt.md +134 -80
- data/docs/logging.md +183 -120
- data/docs/middlewares.md +165 -392
- data/docs/outcomes/result.md +140 -112
- data/docs/outcomes/states.md +134 -99
- data/docs/outcomes/statuses.md +204 -146
- data/docs/parameters/coercions.md +251 -289
- data/docs/parameters/defaults.md +224 -169
- data/docs/parameters/definitions.md +289 -141
- data/docs/parameters/namespacing.md +250 -161
- data/docs/parameters/validations.md +247 -159
- data/docs/testing.md +196 -203
- data/docs/workflows.md +146 -101
- data/lib/cmdx/.DS_Store +0 -0
- data/lib/cmdx/callback.rb +39 -55
- data/lib/cmdx/callback_registry.rb +80 -73
- data/lib/cmdx/chain.rb +65 -122
- data/lib/cmdx/chain_inspector.rb +23 -116
- data/lib/cmdx/chain_serializer.rb +34 -146
- data/lib/cmdx/coercion.rb +57 -0
- data/lib/cmdx/coercion_registry.rb +113 -0
- data/lib/cmdx/coercions/array.rb +18 -36
- data/lib/cmdx/coercions/big_decimal.rb +21 -33
- data/lib/cmdx/coercions/boolean.rb +21 -40
- data/lib/cmdx/coercions/complex.rb +18 -31
- data/lib/cmdx/coercions/date.rb +20 -39
- data/lib/cmdx/coercions/date_time.rb +22 -39
- data/lib/cmdx/coercions/float.rb +19 -32
- data/lib/cmdx/coercions/hash.rb +22 -41
- data/lib/cmdx/coercions/integer.rb +20 -33
- data/lib/cmdx/coercions/rational.rb +20 -32
- data/lib/cmdx/coercions/string.rb +23 -31
- data/lib/cmdx/coercions/time.rb +24 -40
- data/lib/cmdx/coercions/virtual.rb +14 -31
- data/lib/cmdx/configuration.rb +101 -162
- data/lib/cmdx/context.rb +34 -166
- data/lib/cmdx/core_ext/hash.rb +42 -67
- data/lib/cmdx/core_ext/module.rb +35 -79
- data/lib/cmdx/core_ext/object.rb +63 -98
- data/lib/cmdx/correlator.rb +59 -154
- data/lib/cmdx/error.rb +37 -202
- data/lib/cmdx/errors.rb +153 -216
- data/lib/cmdx/fault.rb +68 -150
- data/lib/cmdx/faults.rb +26 -137
- data/lib/cmdx/immutator.rb +22 -110
- data/lib/cmdx/lazy_struct.rb +110 -186
- data/lib/cmdx/log_formatters/json.rb +14 -40
- data/lib/cmdx/log_formatters/key_value.rb +14 -40
- data/lib/cmdx/log_formatters/line.rb +14 -48
- data/lib/cmdx/log_formatters/logstash.rb +14 -57
- data/lib/cmdx/log_formatters/pretty_json.rb +14 -50
- data/lib/cmdx/log_formatters/pretty_key_value.rb +13 -46
- data/lib/cmdx/log_formatters/pretty_line.rb +16 -54
- data/lib/cmdx/log_formatters/raw.rb +19 -49
- data/lib/cmdx/logger.rb +22 -79
- data/lib/cmdx/logger_ansi.rb +31 -72
- data/lib/cmdx/logger_serializer.rb +74 -103
- data/lib/cmdx/middleware.rb +56 -60
- data/lib/cmdx/middleware_registry.rb +82 -77
- data/lib/cmdx/middlewares/correlate.rb +41 -226
- data/lib/cmdx/middlewares/timeout.rb +46 -185
- data/lib/cmdx/parameter.rb +167 -183
- data/lib/cmdx/parameter_evaluator.rb +231 -0
- data/lib/cmdx/parameter_inspector.rb +37 -55
- data/lib/cmdx/parameter_registry.rb +65 -84
- data/lib/cmdx/parameter_serializer.rb +32 -76
- data/lib/cmdx/railtie.rb +24 -107
- data/lib/cmdx/result.rb +254 -259
- data/lib/cmdx/result_ansi.rb +28 -80
- data/lib/cmdx/result_inspector.rb +34 -70
- data/lib/cmdx/result_logger.rb +23 -77
- data/lib/cmdx/result_serializer.rb +59 -125
- data/lib/cmdx/rspec/matchers.rb +28 -0
- data/lib/cmdx/rspec/result_matchers/be_executed.rb +42 -0
- data/lib/cmdx/rspec/result_matchers/be_failed_task.rb +94 -0
- data/lib/cmdx/rspec/result_matchers/be_skipped_task.rb +94 -0
- data/lib/cmdx/rspec/result_matchers/be_state_matchers.rb +59 -0
- data/lib/cmdx/rspec/result_matchers/be_status_matchers.rb +57 -0
- data/lib/cmdx/rspec/result_matchers/be_successful_task.rb +87 -0
- data/lib/cmdx/rspec/result_matchers/have_bad_outcome.rb +51 -0
- data/lib/cmdx/rspec/result_matchers/have_caused_failure.rb +58 -0
- data/lib/cmdx/rspec/result_matchers/have_chain_index.rb +59 -0
- data/lib/cmdx/rspec/result_matchers/have_context.rb +86 -0
- data/lib/cmdx/rspec/result_matchers/have_empty_metadata.rb +54 -0
- data/lib/cmdx/rspec/result_matchers/have_good_outcome.rb +52 -0
- data/lib/cmdx/rspec/result_matchers/have_metadata.rb +114 -0
- data/lib/cmdx/rspec/result_matchers/have_preserved_context.rb +66 -0
- data/lib/cmdx/rspec/result_matchers/have_received_thrown_failure.rb +64 -0
- data/lib/cmdx/rspec/result_matchers/have_runtime.rb +78 -0
- data/lib/cmdx/rspec/result_matchers/have_thrown_failure.rb +76 -0
- data/lib/cmdx/rspec/task_matchers/be_well_formed_task.rb +62 -0
- data/lib/cmdx/rspec/task_matchers/have_callback.rb +85 -0
- data/lib/cmdx/rspec/task_matchers/have_cmd_setting.rb +68 -0
- data/lib/cmdx/rspec/task_matchers/have_executed_callbacks.rb +92 -0
- data/lib/cmdx/rspec/task_matchers/have_middleware.rb +46 -0
- data/lib/cmdx/rspec/task_matchers/have_parameter.rb +181 -0
- data/lib/cmdx/task.rb +336 -427
- data/lib/cmdx/task_deprecator.rb +52 -0
- data/lib/cmdx/task_processor.rb +246 -0
- data/lib/cmdx/task_serializer.rb +34 -69
- data/lib/cmdx/utils/ansi_color.rb +13 -89
- data/lib/cmdx/utils/log_timestamp.rb +13 -42
- data/lib/cmdx/utils/monotonic_runtime.rb +11 -63
- data/lib/cmdx/utils/name_affix.rb +21 -71
- data/lib/cmdx/validator.rb +57 -0
- data/lib/cmdx/validator_registry.rb +108 -0
- data/lib/cmdx/validators/exclusion.rb +55 -94
- data/lib/cmdx/validators/format.rb +31 -85
- data/lib/cmdx/validators/inclusion.rb +65 -110
- data/lib/cmdx/validators/length.rb +117 -133
- data/lib/cmdx/validators/numeric.rb +123 -130
- data/lib/cmdx/validators/presence.rb +38 -79
- data/lib/cmdx/version.rb +1 -7
- data/lib/cmdx/workflow.rb +58 -330
- data/lib/cmdx.rb +1 -1
- data/lib/generators/cmdx/install_generator.rb +14 -31
- data/lib/generators/cmdx/task_generator.rb +39 -55
- data/lib/generators/cmdx/templates/install.rb +24 -6
- data/lib/generators/cmdx/workflow_generator.rb +41 -66
- data/lib/locales/ar.yml +0 -1
- data/lib/locales/cs.yml +0 -1
- data/lib/locales/da.yml +0 -1
- data/lib/locales/de.yml +0 -1
- data/lib/locales/el.yml +0 -1
- data/lib/locales/en.yml +0 -1
- data/lib/locales/es.yml +0 -1
- data/lib/locales/fi.yml +0 -1
- data/lib/locales/fr.yml +0 -1
- data/lib/locales/he.yml +0 -1
- data/lib/locales/hi.yml +0 -1
- data/lib/locales/it.yml +0 -1
- data/lib/locales/ja.yml +0 -1
- data/lib/locales/ko.yml +0 -1
- data/lib/locales/nl.yml +0 -1
- data/lib/locales/no.yml +0 -1
- data/lib/locales/pl.yml +0 -1
- data/lib/locales/pt.yml +0 -1
- data/lib/locales/ru.yml +0 -1
- data/lib/locales/sv.yml +0 -1
- data/lib/locales/th.yml +0 -1
- data/lib/locales/tr.yml +0 -1
- data/lib/locales/vi.yml +0 -1
- data/lib/locales/zh.yml +0 -1
- metadata +36 -8
- data/lib/cmdx/parameter_validator.rb +0 -81
- data/lib/cmdx/parameter_value.rb +0 -244
- data/lib/cmdx/parameters_inspector.rb +0 -72
- data/lib/cmdx/parameters_serializer.rb +0 -115
- data/lib/cmdx/rspec/result_matchers.rb +0 -917
- data/lib/cmdx/rspec/task_matchers.rb +0 -570
- data/lib/cmdx/validators/custom.rb +0 -102
data/docs/outcomes/result.md
CHANGED
@@ -1,9 +1,6 @@
|
|
1
1
|
# Outcomes - Result
|
2
2
|
|
3
|
-
The result object is the comprehensive return value of task execution, providing
|
4
|
-
complete information about the execution outcome, state, timing, and any data
|
5
|
-
produced during the task lifecycle. Results serve as the primary interface for
|
6
|
-
inspecting task execution outcomes and chaining task operations.
|
3
|
+
The result object is the comprehensive return value of task execution, providing complete information about the execution outcome, state, timing, and any data produced during the task lifecycle. Results serve as the primary interface for inspecting task execution outcomes and chaining task operations.
|
7
4
|
|
8
5
|
## Table of Contents
|
9
6
|
|
@@ -20,228 +17,261 @@ inspecting task execution outcomes and chaining task operations.
|
|
20
17
|
|
21
18
|
## TLDR
|
22
19
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
20
|
+
```ruby
|
21
|
+
# Basic result inspection
|
22
|
+
result = ProcessOrderTask.call(order_id: 123)
|
23
|
+
result.success? # → true/false
|
24
|
+
result.failed? # → true/false
|
25
|
+
result.runtime # → 0.5 (seconds)
|
26
|
+
|
27
|
+
# Fluent callbacks
|
28
|
+
result
|
29
|
+
.on_success { |r| send_notification(r.context) }
|
30
|
+
.on_failed { |r| handle_error(r.metadata) }
|
31
|
+
|
32
|
+
# Failure chain analysis
|
33
|
+
if result.failed?
|
34
|
+
original = result.caused_failure # Find root cause
|
35
|
+
thrower = result.threw_failure # Find failure source
|
36
|
+
end
|
37
|
+
```
|
28
38
|
|
29
39
|
## Core Result Attributes
|
30
40
|
|
41
|
+
> [!NOTE]
|
42
|
+
> Result objects are immutable after task execution completes. All result data reflects the final state of the task execution and cannot be modified.
|
43
|
+
|
31
44
|
Every result provides access to essential execution information:
|
32
45
|
|
33
46
|
```ruby
|
34
|
-
result =
|
47
|
+
result = ProcessOrderTask.call(order_id: 123)
|
35
48
|
|
36
49
|
# Core objects
|
37
|
-
result.task
|
38
|
-
result.context
|
39
|
-
result.chain
|
40
|
-
result.metadata
|
50
|
+
result.task # → ProcessOrderTask instance
|
51
|
+
result.context # → CMDx::Context with all task data
|
52
|
+
result.chain # → CMDx::Chain execution tracking
|
53
|
+
result.metadata # → Hash with execution metadata
|
41
54
|
|
42
55
|
# Execution information
|
43
|
-
result.id
|
44
|
-
result.state
|
45
|
-
result.status
|
46
|
-
result.runtime
|
56
|
+
result.id # → "abc123..." (unique execution ID)
|
57
|
+
result.state # → "complete"
|
58
|
+
result.status # → "success"
|
59
|
+
result.runtime # → 0.5 (execution time in seconds)
|
47
60
|
```
|
48
61
|
|
49
|
-
> [!NOTE]
|
50
|
-
> Result objects are immutable after task execution completes. All result data reflects the final state of the task execution and cannot be modified.
|
51
|
-
|
52
62
|
## State and Status Information
|
53
63
|
|
54
64
|
Results provide comprehensive methods for checking execution state and status:
|
55
65
|
|
56
66
|
```ruby
|
57
|
-
result =
|
67
|
+
result = ProcessOrderTask.call(order_id: 123)
|
58
68
|
|
59
69
|
# State predicates (execution lifecycle)
|
60
|
-
result.
|
61
|
-
result.
|
62
|
-
result.
|
63
|
-
result.interrupted? #=> false (no interruption)
|
64
|
-
result.executed? #=> true (execution finished)
|
70
|
+
result.complete? # → true (successful completion)
|
71
|
+
result.interrupted? # → false (no interruption)
|
72
|
+
result.executed? # → true (execution finished)
|
65
73
|
|
66
74
|
# Status predicates (execution outcome)
|
67
|
-
result.success?
|
68
|
-
result.
|
69
|
-
result.
|
75
|
+
result.success? # → true (successful execution)
|
76
|
+
result.failed? # → false (no failure)
|
77
|
+
result.skipped? # → false (not skipped)
|
70
78
|
|
71
79
|
# Outcome categorization
|
72
|
-
result.good?
|
73
|
-
result.bad?
|
80
|
+
result.good? # → true (success or skipped)
|
81
|
+
result.bad? # → false (failed only)
|
74
82
|
```
|
75
83
|
|
76
84
|
## Execution Outcome Analysis
|
77
85
|
|
78
|
-
Results provide
|
86
|
+
Results provide unified outcome determination:
|
79
87
|
|
80
88
|
```ruby
|
81
|
-
result =
|
89
|
+
result = ProcessOrderTask.call(order_id: 123)
|
82
90
|
|
83
|
-
#
|
84
|
-
result.outcome #=> "success" (combines state and status)
|
91
|
+
result.outcome # → "success" (combines state and status)
|
85
92
|
```
|
86
93
|
|
87
94
|
## Runtime and Performance
|
88
95
|
|
89
|
-
Results capture detailed timing information:
|
96
|
+
Results capture detailed timing information for performance analysis:
|
90
97
|
|
91
98
|
```ruby
|
92
|
-
result =
|
99
|
+
result = ProcessOrderTask.call(order_id: 123)
|
93
100
|
|
94
101
|
# Execution timing
|
95
|
-
result.runtime
|
102
|
+
result.runtime # → 0.5 (total execution time in seconds)
|
103
|
+
|
104
|
+
# Performance monitoring
|
105
|
+
result
|
106
|
+
.on_executed { |r|
|
107
|
+
MetricsService.record_execution_time(r.task.class.name, r.runtime)
|
108
|
+
}
|
96
109
|
```
|
97
110
|
|
98
111
|
## Failure Chain Analysis
|
99
112
|
|
113
|
+
> [!IMPORTANT]
|
114
|
+
> Failure chain analysis is only available for failed results. Use these methods to trace the root cause of failures in complex task workflows.
|
115
|
+
|
100
116
|
For failed results, comprehensive failure analysis is available:
|
101
117
|
|
102
118
|
```ruby
|
103
|
-
result = ProcessOrderWorkflowTask.call
|
119
|
+
result = ProcessOrderWorkflowTask.call(order_id: 123)
|
104
120
|
|
105
121
|
if result.failed?
|
106
122
|
# Find the original cause of failure
|
107
|
-
original_failure = result.caused_failure
|
108
|
-
|
109
|
-
puts "Original failure: #{original_failure.task.class.name}"
|
123
|
+
if original_failure = result.caused_failure
|
124
|
+
puts "Root cause: #{original_failure.task.class.name}"
|
110
125
|
puts "Reason: #{original_failure.metadata[:reason]}"
|
111
126
|
end
|
112
127
|
|
113
128
|
# Find what threw the failure to this result
|
114
|
-
throwing_task = result.threw_failure
|
115
|
-
|
116
|
-
puts "Failure thrown by: #{throwing_task.task.class.name}"
|
129
|
+
if throwing_task = result.threw_failure
|
130
|
+
puts "Failure source: #{throwing_task.task.class.name}"
|
117
131
|
end
|
118
132
|
|
119
133
|
# Failure classification
|
120
|
-
result.caused_failure?
|
121
|
-
result.threw_failure?
|
122
|
-
result.thrown_failure?
|
134
|
+
result.caused_failure? # → true if this result was the original cause
|
135
|
+
result.threw_failure? # → true if this result threw a failure
|
136
|
+
result.thrown_failure? # → true if this result received a thrown failure
|
123
137
|
end
|
124
138
|
```
|
125
139
|
|
126
|
-
|
127
|
-
|
140
|
+
### Error Handling Patterns
|
141
|
+
|
142
|
+
```ruby
|
143
|
+
result = ProcessPaymentTask.call(amount: "invalid")
|
144
|
+
|
145
|
+
if result.failed?
|
146
|
+
case result.metadata[:reason]
|
147
|
+
when /validation/i
|
148
|
+
handle_validation_error(result)
|
149
|
+
when /network/i
|
150
|
+
schedule_retry(result)
|
151
|
+
else
|
152
|
+
escalate_error(result)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
```
|
128
156
|
|
129
157
|
## Index and Position
|
130
158
|
|
131
159
|
Results track their position within execution chains:
|
132
160
|
|
133
161
|
```ruby
|
134
|
-
result =
|
162
|
+
result = ProcessOrderTask.call(order_id: 123)
|
135
163
|
|
136
164
|
# Position in execution sequence
|
137
|
-
result.index
|
165
|
+
result.index # → 0 (first task in chain)
|
138
166
|
|
139
167
|
# Access via chain
|
140
|
-
result.chain.results[result.index] == result
|
168
|
+
result.chain.results[result.index] == result # → true
|
141
169
|
```
|
142
170
|
|
143
171
|
## Result Callbacks and Chaining
|
144
172
|
|
173
|
+
> [!TIP]
|
174
|
+
> Use result callbacks for clean, functional-style conditional logic. Callbacks return the result object, enabling method chaining and fluent interfaces.
|
175
|
+
|
145
176
|
Results support fluent callback patterns for conditional logic:
|
146
177
|
|
147
178
|
```ruby
|
148
|
-
result =
|
179
|
+
result = ProcessOrderTask.call(order_id: 123)
|
149
180
|
|
150
|
-
#
|
181
|
+
# Status-based callbacks
|
151
182
|
result
|
152
|
-
.
|
153
|
-
.
|
154
|
-
.
|
183
|
+
.on_success { |r| send_confirmation_email(r.context.email) }
|
184
|
+
.on_failed { |r| handle_payment_failure(r) }
|
185
|
+
.on_skipped { |r| log_skip_reason(r.metadata[:reason]) }
|
155
186
|
|
156
|
-
#
|
187
|
+
# State-based callbacks
|
157
188
|
result
|
158
|
-
.
|
159
|
-
.
|
160
|
-
.on_failed { |r| handle_failure(r) }
|
189
|
+
.on_complete { |r| update_order_status("processed") }
|
190
|
+
.on_interrupted { |r| cleanup_partial_state(r.context) }
|
161
191
|
|
162
192
|
# Outcome-based callbacks
|
163
193
|
result
|
164
|
-
.on_good { |r|
|
165
|
-
.on_bad { |r|
|
194
|
+
.on_good { |r| increment_success_counter }
|
195
|
+
.on_bad { |r| alert_operations_team }
|
166
196
|
```
|
167
197
|
|
168
|
-
### Callback
|
198
|
+
### Practical Callback Examples
|
169
199
|
|
170
200
|
```ruby
|
171
|
-
|
172
|
-
|
201
|
+
# Order processing pipeline
|
202
|
+
ProcessOrderTask
|
203
|
+
.call(order_id: params[:order_id])
|
173
204
|
.on_success { |result|
|
174
|
-
|
205
|
+
# Chain to notification task
|
206
|
+
SendOrderConfirmationTask.call(result.context)
|
175
207
|
}
|
176
208
|
.on_failed { |result|
|
177
|
-
|
209
|
+
# Handle specific failure types
|
210
|
+
case result.metadata[:error_type]
|
211
|
+
when "payment_declined"
|
212
|
+
redirect_to payment_retry_path
|
213
|
+
when "inventory_unavailable"
|
214
|
+
redirect_to out_of_stock_path
|
215
|
+
else
|
216
|
+
redirect_to error_path
|
217
|
+
end
|
178
218
|
}
|
179
219
|
.on_executed { |result|
|
180
|
-
|
220
|
+
# Always log performance metrics
|
221
|
+
Rails.logger.info "Order processing took #{result.runtime}s"
|
181
222
|
}
|
182
223
|
```
|
183
224
|
|
184
|
-
> [!TIP]
|
185
|
-
> Use result callbacks for clean, functional-style conditional logic. Callbacks return the result object, enabling method chaining and fluent interfaces.
|
186
|
-
|
187
225
|
## Pattern Matching
|
188
226
|
|
189
|
-
|
227
|
+
> [!NOTE]
|
228
|
+
> Pattern matching requires Ruby 3.0+. The `deconstruct` method returns `[state, status]` for array patterns, while `deconstruct_keys` provides hash access to result attributes.
|
229
|
+
|
230
|
+
Results support Ruby's pattern matching through array and hash deconstruction:
|
190
231
|
|
191
232
|
### Array Pattern Matching
|
192
233
|
|
193
|
-
Match against state and status in order:
|
194
|
-
|
195
234
|
```ruby
|
196
|
-
result =
|
235
|
+
result = ProcessOrderTask.call(order_id: 123)
|
197
236
|
|
198
237
|
case result
|
199
238
|
in ["complete", "success"]
|
200
|
-
|
239
|
+
redirect_to success_page
|
201
240
|
in ["interrupted", "failed"]
|
202
|
-
|
241
|
+
retry_with_backoff(result)
|
203
242
|
in ["complete", "skipped"]
|
204
|
-
|
243
|
+
log_skip_and_continue
|
205
244
|
end
|
206
245
|
```
|
207
246
|
|
208
247
|
### Hash Pattern Matching
|
209
248
|
|
210
|
-
Match against specific result attributes:
|
211
|
-
|
212
249
|
```ruby
|
213
|
-
result =
|
250
|
+
result = ProcessOrderTask.call(order_id: 123)
|
214
251
|
|
215
252
|
case result
|
216
253
|
in { state: "complete", status: "success" }
|
217
|
-
|
218
|
-
in {
|
219
|
-
|
220
|
-
in { good: true }
|
221
|
-
puts "Execution went well overall"
|
254
|
+
celebrate_success
|
255
|
+
in { status: "failed", metadata: { retryable: true } }
|
256
|
+
schedule_retry(result)
|
222
257
|
in { bad: true, metadata: { reason: String => reason } }
|
223
|
-
|
258
|
+
escalate_error("Failed: #{reason}")
|
224
259
|
end
|
225
260
|
```
|
226
261
|
|
227
262
|
### Pattern Matching with Guards
|
228
263
|
|
229
|
-
Use guard clauses for conditional matching:
|
230
|
-
|
231
264
|
```ruby
|
232
265
|
case result
|
233
266
|
in { status: "failed", metadata: { attempts: n } } if n < 3
|
234
|
-
|
267
|
+
retry_task_with_delay(result, n * 2)
|
235
268
|
in { status: "failed", metadata: { attempts: n } } if n >= 3
|
236
|
-
|
237
|
-
in { runtime: time } if time >
|
238
|
-
|
269
|
+
mark_permanently_failed(result)
|
270
|
+
in { runtime: time } if time > performance_threshold
|
271
|
+
investigate_performance_issue(result)
|
239
272
|
end
|
240
273
|
```
|
241
274
|
|
242
|
-
> [!NOTE]
|
243
|
-
> Pattern matching requires Ruby 3.0+. The `deconstruct` method returns `[state, status]` for array patterns, while `deconstruct_keys` provides hash access to `state`, `status`, `metadata`, `executed`, `good`, and `bad` attributes.
|
244
|
-
|
245
275
|
## Serialization and Inspection
|
246
276
|
|
247
277
|
Results provide comprehensive serialization and inspection capabilities:
|
@@ -249,11 +279,11 @@ Results provide comprehensive serialization and inspection capabilities:
|
|
249
279
|
### Hash Serialization
|
250
280
|
|
251
281
|
```ruby
|
252
|
-
result =
|
282
|
+
result = ProcessOrderTask.call(order_id: 123)
|
253
283
|
|
254
284
|
result.to_h
|
255
|
-
|
256
|
-
# class: "
|
285
|
+
# → {
|
286
|
+
# class: "ProcessOrderTask",
|
257
287
|
# type: "Task",
|
258
288
|
# index: 0,
|
259
289
|
# id: "abc123...",
|
@@ -270,31 +300,32 @@ result.to_h
|
|
270
300
|
### Human-Readable Inspection
|
271
301
|
|
272
302
|
```ruby
|
273
|
-
result =
|
303
|
+
result = ProcessOrderTask.call(order_id: 123)
|
274
304
|
|
275
305
|
result.to_s
|
276
|
-
|
306
|
+
# → "ProcessOrderTask: type=Task index=0 id=abc123... state=complete status=success outcome=success metadata={} runtime=0.5"
|
277
307
|
```
|
278
308
|
|
279
309
|
### Failure Chain Serialization
|
280
310
|
|
281
|
-
|
311
|
+
> [!WARNING]
|
312
|
+
> Failed results include complete failure chain information. This data can be substantial in complex workflows - consider filtering when logging or persisting.
|
282
313
|
|
283
314
|
```ruby
|
284
|
-
failed_result = ProcessOrderWorkflowTask.call
|
315
|
+
failed_result = ProcessOrderWorkflowTask.call(order_id: 123)
|
285
316
|
|
286
317
|
failed_result.to_h
|
287
|
-
|
318
|
+
# → {
|
288
319
|
# # ... standard result data ...
|
289
320
|
# caused_failure: {
|
290
|
-
# class: "
|
321
|
+
# class: "ValidateOrderTask",
|
291
322
|
# index: 1,
|
292
323
|
# id: "xyz789...",
|
293
324
|
# state: "interrupted",
|
294
325
|
# status: "failed"
|
295
326
|
# },
|
296
327
|
# threw_failure: {
|
297
|
-
# class: "
|
328
|
+
# class: "ProcessPaymentTask",
|
298
329
|
# index: 2,
|
299
330
|
# id: "uvw123...",
|
300
331
|
# state: "interrupted",
|
@@ -303,9 +334,6 @@ failed_result.to_h
|
|
303
334
|
# }
|
304
335
|
```
|
305
336
|
|
306
|
-
> [!NOTE]
|
307
|
-
> Serialized results include complete failure chain information for debugging and audit trails. Use `to_h` for structured data and `to_s` for human-readable output.
|
308
|
-
|
309
337
|
---
|
310
338
|
|
311
339
|
- **Prev:** [Interruptions - Exceptions](../interruptions/exceptions.md)
|