Class: CMDx::Task
- Inherits:
-
Object
- Object
- CMDx::Task
- Defined in:
- lib/cmdx/task.rb
Overview
Base class for all units of work. Subclasses override ‘#work` and declare their contract via `required`, `optional`, `output`, `callbacks`, `retry_on`, `deprecation`, and `settings`. Invoked via Task.execute (safe) or Task.execute! (strict, raises on failure).
Inheritance: every registry accessor (middlewares, callbacks, coercions, validators, executors, mergers, telemetry, inputs, outputs) lazily clones from the superclass’s registry (or the global configuration at the top of the hierarchy), so subclasses extend rather than replace.
Instance Attribute Summary collapse
-
#context ⇒ Object
(also: #ctx)
readonly
Returns the value of attribute context.
-
#errors ⇒ Object
readonly
Returns the value of attribute errors.
-
#metadata ⇒ Object
readonly
Returns the value of attribute metadata.
-
#tid ⇒ Object
readonly
Returns the value of attribute tid.
Class Method Summary collapse
-
.call {|result| ... } ⇒ Result, Object
Executes the task.
-
.callbacks ⇒ Callbacks
Cloned from superclass/configuration on first call.
-
.coercions ⇒ Coercions
Cloned from superclass/configuration on first call.
-
.deprecation(value = nil, **options, &block) { ... } ⇒ Deprecation?
Reads, sets, or inherits the task class’s Deprecation.
-
.deprecators ⇒ Deprecators
Cloned from superclass/configuration on first call.
-
.deregister(type) ⇒ Object
Dispatches to the appropriate registry’s ‘deregister` method.
-
.execute(context = EMPTY_HASH) {|result| ... } ⇒ Result, Object
Executes the task.
-
.execute!(context = EMPTY_HASH) {|result| ... } ⇒ Result, Object
(also: call!)
Strict execution.
-
.executors ⇒ Executors
Cloned from superclass/configuration on first call.
-
.inputs(*names, **options) { ... } ⇒ Inputs
(also: input)
Reads, or declares more, inputs.
-
.inputs_schema ⇒ Hash{Symbol => Hash}
Serialized input definitions.
-
.mergers ⇒ Mergers
Cloned from superclass/configuration on first call.
-
.middlewares ⇒ Middlewares
Cloned from superclass/configuration on first call.
-
.optional(*names, **options) { ... } ⇒ Object
Declares optional inputs (shorthand for ‘inputs …, required: false`).
-
.outputs(*keys, **options) ⇒ Outputs
(also: output)
Reads, or declares more, outputs.
-
.outputs_schema ⇒ Hash{Symbol => Hash}
Serialized output definitions.
-
.register(type) ⇒ Object
Dispatches to the appropriate registry’s ‘register` method.
-
.required(*names, **options) { ... } ⇒ Object
Declares required inputs (shorthand for ‘inputs …, required: true`).
-
.retriers ⇒ Retriers
Cloned from superclass/configuration on first call.
-
.retry_on(*exceptions, **options) {|attempt, delay| ... } ⇒ Retry
Declares exceptions to retry on.
-
.settings(options = EMPTY_HASH) ⇒ Settings
Reads or extends this class’s Settings.
-
.telemetry ⇒ Telemetry
Cloned from superclass/configuration on first call.
-
.type ⇒ String
‘“Workflow”` when the class includes Workflow, else `“Task”`.
-
.validators ⇒ Validators
Cloned from superclass/configuration on first call.
Instance Method Summary collapse
-
#execute(strict: false) {|result| ... } ⇒ Result, Object
(also: #call)
Executes this task instance through Runtime.
-
#initialize(context = EMPTY_HASH) ⇒ Task
constructor
A new instance of Task.
-
#logger ⇒ Logger
A logger tailored to this task’s settings.
-
#work ⇒ void
abstract
The task’s core logic.
Constructor Details
#initialize(context = EMPTY_HASH) ⇒ Task
The built Context inherits ‘strict` mode from Settings#strict_context (falling back to Configuration#strict_context), so dynamic reads for unknown keys raise `NoMethodError` instead of returning `nil`.
Returns a new instance of Task.
418 419 420 421 422 423 424 425 |
# File 'lib/cmdx/task.rb', line 418 def initialize(context = EMPTY_HASH) @metadata = {} @tid = SecureRandom.uuid_v7 @errors = Errors.new @context = Context.build(context).tap do |c| c.strict = self.class.settings.strict_context end end |
Instance Attribute Details
#context ⇒ Object (readonly) Also known as: ctx
Returns the value of attribute context.
410 411 412 |
# File 'lib/cmdx/task.rb', line 410 def context @context end |
#errors ⇒ Object (readonly)
Returns the value of attribute errors.
410 411 412 |
# File 'lib/cmdx/task.rb', line 410 def errors @errors end |
#metadata ⇒ Object (readonly)
Returns the value of attribute metadata.
410 411 412 |
# File 'lib/cmdx/task.rb', line 410 def @metadata end |
#tid ⇒ Object (readonly)
Returns the value of attribute tid.
410 411 412 |
# File 'lib/cmdx/task.rb', line 410 def tid @tid end |
Class Method Details
.call {|result| ... } ⇒ Result, Object
Executes the task. Never raises on failure; inspect the returned Result instead.
369 370 371 |
# File 'lib/cmdx/task.rb', line 369 def execute(context = EMPTY_HASH, &) new(context).execute(strict: false, &) end |
.callbacks ⇒ Callbacks
Returns cloned from superclass/configuration on first call.
81 82 83 84 85 86 87 88 |
# File 'lib/cmdx/task.rb', line 81 def callbacks @callbacks ||= if superclass.respond_to?(:callbacks) superclass.callbacks.dup else CMDx.configuration.callbacks.dup end end |
.coercions ⇒ Coercions
Returns cloned from superclass/configuration on first call.
107 108 109 110 111 112 113 114 |
# File 'lib/cmdx/task.rb', line 107 def coercions @coercions ||= if superclass.respond_to?(:coercions) superclass.coercions.dup else CMDx.configuration.coercions.dup end end |
.deprecation(value = nil, **options, &block) { ... } ⇒ Deprecation?
Reads, sets, or inherits the task class’s Deprecation. With a ‘value` or block, replaces any current deprecation. Otherwise returns the locally defined one, or the superclass’s.
239 240 241 242 243 244 245 246 247 |
# File 'lib/cmdx/task.rb', line 239 def deprecation(value = nil, **, &block) if value || block @deprecation = Deprecation.new(value || block, ) elsif defined?(@deprecation) @deprecation elsif superclass.respond_to?(:deprecation) superclass.deprecation end end |
.deprecators ⇒ Deprecators
Returns cloned from superclass/configuration on first call.
157 158 159 160 161 162 163 164 |
# File 'lib/cmdx/task.rb', line 157 def deprecators @deprecators ||= if superclass.respond_to?(:deprecators) superclass.deprecators.dup else CMDx.configuration.deprecators.dup end end |
.deregister(type) ⇒ Object
Dispatches to the appropriate registry’s ‘deregister` method.
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 |
# File 'lib/cmdx/task.rb', line 202 def deregister(type, ...) case type when :middleware middlewares.deregister(...) when :callback callbacks.deregister(...) when :coercion coercions.deregister(...) when :validator validators.deregister(...) when :executor executors.deregister(...) when :merger mergers.deregister(...) when :retrier retriers.deregister(...) when :deprecator deprecators.deregister(...) when :input inputs.deregister(self, ...) when :output outputs.deregister(...) else raise ArgumentError, "unknown registry type: #{type.inspect}" end end |
.execute(context = EMPTY_HASH) {|result| ... } ⇒ Result, Object
Executes the task. Never raises on failure; inspect the returned Result instead.
366 367 368 |
# File 'lib/cmdx/task.rb', line 366 def execute(context = EMPTY_HASH, &) new(context).execute(strict: false, &) end |
.execute!(context = EMPTY_HASH) {|result| ... } ⇒ Result, Object Also known as: call!
378 379 380 |
# File 'lib/cmdx/task.rb', line 378 def execute!(context = EMPTY_HASH, &) new(context).execute(strict: true, &) end |
.executors ⇒ Executors
Returns cloned from superclass/configuration on first call.
127 128 129 130 131 132 133 134 |
# File 'lib/cmdx/task.rb', line 127 def executors @executors ||= if superclass.respond_to?(:executors) superclass.executors.dup else CMDx.configuration.executors.dup end end |
.inputs(*names, **options) { ... } ⇒ Inputs Also known as: input
Reads, or declares more, inputs. With no names, returns the registry; with names, registers them and defines accessors.
268 269 270 271 272 273 274 275 276 277 278 279 |
# File 'lib/cmdx/task.rb', line 268 def inputs(*names, **, &) @inputs ||= if superclass.respond_to?(:inputs) superclass.inputs.dup else Inputs.new end return @inputs if names.empty? @inputs.register(self, *names, **, &) end |
.inputs_schema ⇒ Hash{Symbol => Hash}
Returns serialized input definitions.
323 324 325 |
# File 'lib/cmdx/task.rb', line 323 def inputs_schema inputs.registry.transform_values(&:to_h) end |
.mergers ⇒ Mergers
Returns cloned from superclass/configuration on first call.
137 138 139 140 141 142 143 144 |
# File 'lib/cmdx/task.rb', line 137 def mergers @mergers ||= if superclass.respond_to?(:mergers) superclass.mergers.dup else CMDx.configuration.mergers.dup end end |
.middlewares ⇒ Middlewares
Returns cloned from superclass/configuration on first call.
71 72 73 74 75 76 77 78 |
# File 'lib/cmdx/task.rb', line 71 def middlewares @middlewares ||= if superclass.respond_to?(:middlewares) superclass.middlewares.dup else CMDx.configuration.middlewares.dup end end |
.optional(*names, **options) { ... } ⇒ Object
Declares optional inputs (shorthand for ‘inputs …, required: false`).
298 299 300 |
# File 'lib/cmdx/task.rb', line 298 def optional(*names, **, &) register(:input, *names, required: false, **, &) end |
.outputs(*keys, **options) ⇒ Outputs Also known as: output
Reads, or declares more, outputs. With no keys, returns the registry.
336 337 338 339 340 341 342 343 344 345 346 347 |
# File 'lib/cmdx/task.rb', line 336 def outputs(*keys, **) @outputs ||= if superclass.respond_to?(:outputs) superclass.outputs.dup else Outputs.new end return @outputs if keys.empty? @outputs.register(*keys, **) end |
.outputs_schema ⇒ Hash{Symbol => Hash}
Returns serialized output definitions.
351 352 353 |
# File 'lib/cmdx/task.rb', line 351 def outputs_schema outputs.registry.transform_values(&:to_h) end |
.register(type) ⇒ Object
Dispatches to the appropriate registry’s ‘register` method.
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 |
# File 'lib/cmdx/task.rb', line 171 def register(type, ...) case type when :middleware middlewares.register(...) when :callback callbacks.register(...) when :coercion coercions.register(...) when :validator validators.register(...) when :executor executors.register(...) when :merger mergers.register(...) when :retrier retriers.register(...) when :deprecator deprecators.register(...) when :input inputs.register(self, ...) when :output outputs.register(...) else raise ArgumentError, "unknown registry type: #{type.inspect}" end end |
.required(*names, **options) { ... } ⇒ Object
Declares required inputs (shorthand for ‘inputs …, required: true`).
318 319 320 |
# File 'lib/cmdx/task.rb', line 318 def required(*names, **, &) register(:input, *names, required: true, **, &) end |
.retriers ⇒ Retriers
Returns cloned from superclass/configuration on first call.
147 148 149 150 151 152 153 154 |
# File 'lib/cmdx/task.rb', line 147 def retriers @retriers ||= if superclass.respond_to?(:retriers) superclass.retriers.dup else CMDx.configuration.retriers.dup end end |
.retry_on(*exceptions, **options) {|attempt, delay| ... } ⇒ Retry
Declares exceptions to retry on. Builds on the superclass’s ‘Retry`. Passing no exceptions returns the current (possibly inherited) Retry.
33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/cmdx/task.rb', line 33 def retry_on(*exceptions, **, &) @retry_on ||= if superclass.respond_to?(:retry_on) superclass.retry_on.build(exceptions, , &) else Retry.new(exceptions, , &) end return @retry_on if exceptions.empty? @retry_on = @retry_on.build(exceptions, , &) end |
.settings(options = EMPTY_HASH) ⇒ Settings
Reads or extends this class’s Settings. Inherits from the superclass.
57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/cmdx/task.rb', line 57 def settings( = EMPTY_HASH) @settings ||= if superclass.respond_to?(:settings) superclass.settings.build() else Settings.new() end return @settings if .empty? @settings = @settings.build() end |
.telemetry ⇒ Telemetry
Returns cloned from superclass/configuration on first call.
97 98 99 100 101 102 103 104 |
# File 'lib/cmdx/task.rb', line 97 def telemetry @telemetry ||= if superclass.respond_to?(:telemetry) superclass.telemetry.dup else CMDx.configuration.telemetry.dup end end |
.type ⇒ String
Returns ‘“Workflow”` when the class includes Workflow, else `“Task”`.
356 357 358 |
# File 'lib/cmdx/task.rb', line 356 def type @type ||= include?(Workflow) ? "Workflow" : "Task" end |
.validators ⇒ Validators
Returns cloned from superclass/configuration on first call.
117 118 119 120 121 122 123 124 |
# File 'lib/cmdx/task.rb', line 117 def validators @validators ||= if superclass.respond_to?(:validators) superclass.validators.dup else CMDx.configuration.validators.dup end end |
Instance Method Details
#execute(strict: false) {|result| ... } ⇒ Result, Object Also known as: call
Executes this task instance through Runtime.
435 436 437 438 |
# File 'lib/cmdx/task.rb', line 435 def execute(strict: false) result = Runtime.execute(self, strict:) block_given? ? yield(result) : result end |
#logger ⇒ Logger
Returns a logger tailored to this task’s settings.
442 443 444 |
# File 'lib/cmdx/task.rb', line 442 def logger @logger ||= LoggerProxy.logger(self) end |
#work ⇒ void
This method returns an undefined value.
The task’s core logic. Subclasses must override.
451 452 453 |
# File 'lib/cmdx/task.rb', line 451 def work raise ImplementationError, "undefined method #{self.class}#work" end |