Class: Hubbado::Sequence::Pipeline
- Inherits:
-
Object
- Object
- Hubbado::Sequence::Pipeline
- Defined in:
- lib/hubbado/sequence/pipeline.rb
Class Method Summary collapse
-
.call(ctx = nil, **kwargs, &block) ⇒ Object
‘Pipeline.(ctx) { |p| … }` is the block form: yields the pipeline, runs the block (so steps can be added in statement form), and returns the final Result.
Instance Method Summary collapse
-
#initialize(ctx, dispatcher: nil) ⇒ Pipeline
constructor
A new instance of Pipeline.
-
#invoke(name, *args, **kwargs) ⇒ Object
‘invoke(:name, *args, **kwargs)` calls a declared dependency on the sequencer: gets the dependency via `dispatcher.send(name)` (the reader), then invokes it with `(ctx, *args, **kwargs)`.
- #result ⇒ Object
-
#step(name, &block) ⇒ Object
‘step(:name) { |ctx| … }` runs the block.
- #transaction(&block) ⇒ Object
Constructor Details
#initialize(ctx, dispatcher: nil) ⇒ Pipeline
Returns a new instance of Pipeline.
27 28 29 30 31 32 |
# File 'lib/hubbado/sequence/pipeline.rb', line 27 def initialize(ctx, dispatcher: nil) @ctx = ctx @trail = [] @failed_result = nil @dispatcher = dispatcher end |
Class Method Details
.call(ctx = nil, **kwargs, &block) ⇒ Object
‘Pipeline.(ctx) { |p| … }` is the block form: yields the pipeline, runs the block (so steps can be added in statement form), and returns the final Result. The non-block form returns the Pipeline so chained `.step(…)…result` calls still work.
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
# File 'lib/hubbado/sequence/pipeline.rb', line 8 def self.call(ctx = nil, **kwargs, &block) if ctx.nil? ctx = Ctx.build(kwargs) elsif !kwargs.empty? raise ArgumentError, "Pipeline.() takes either a Ctx or keyword arguments, not both" elsif !ctx.is_a?(Ctx) ctx = Ctx.build(ctx) end pipe = new(ctx) if block block.call(pipe) pipe.result else pipe end end |
Instance Method Details
#invoke(name, *args, **kwargs) ⇒ Object
‘invoke(:name, *args, **kwargs)` calls a declared dependency on the sequencer: gets the dependency via `dispatcher.send(name)` (the reader), then invokes it with `(ctx, *args, **kwargs)`. Same trail recording, failure short-circuiting, and lenient return convention as `step`.
Use this for any declared dependency — macros (‘Macros::Model::Find`) and nested sequencers (`Seqs::Present`) alike. Use `step` for local instance methods like `def deserialize_contract(ctx)`.
67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/hubbado/sequence/pipeline.rb', line 67 def invoke(name, *args, **kwargs) return self if @failed_result return_value = invoke_dependency(name, args, kwargs) if return_value.is_a?(Result) && return_value.failure? @failed_result = tag_failure(return_value, name) else @trail << name end self end |
#result ⇒ Object
96 97 98 99 100 101 102 |
# File 'lib/hubbado/sequence/pipeline.rb', line 96 def result if @failed_result @failed_result else Result.ok(@ctx, trail: @trail.dup) end end |
#step(name, &block) ⇒ Object
‘step(:name) { |ctx| … }` runs the block. `step(:name)` with no block dispatches to `dispatcher.send(name, ctx)` on the sequencer that built this pipeline (via the mixin’s ‘pipeline(ctx)` helper). Block beats dispatch when both are available; raises if neither.
Lenient return convention: a step is treated as successful unless it explicitly returns a failed ‘Result`. Any other return value (nil, false, a model, a hash, `Result.ok(…)`) is taken as success and the pipeline continues with the same `@ctx`. Only `Result.fail(…)` / `failure(ctx, code: …)` short-circuits the pipeline.
44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/hubbado/sequence/pipeline.rb', line 44 def step(name, &block) return self if @failed_result return_value = invoke_step(name, block) if return_value.is_a?(Result) && return_value.failure? @failed_result = tag_failure(return_value, name) else @trail << name end self end |
#transaction(&block) ⇒ Object
81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/hubbado/sequence/pipeline.rb', line 81 def transaction(&block) return self if @failed_result if defined?(::ActiveRecord::Base) ::ActiveRecord::Base.transaction do yield(self) raise ::ActiveRecord::Rollback if @failed_result end else yield(self) end self end |