Class: SenroUsecaser::Base
- Inherits:
-
Object
- Object
- SenroUsecaser::Base
- Extended by:
- DependsOn
- Defined in:
- lib/senro_usecaser/base.rb
Overview
Base class for all UseCases
Defined Under Namespace
Classes: StepExecutionRecord
Class Attribute Summary collapse
-
.organized_steps ⇒ Object
readonly
Returns the list of organized steps.
-
.output_schema ⇒ Object
readonly
Returns the output schema.
Class Method Summary collapse
-
.after(&block) ⇒ Object
Adds an after hook.
-
.after_hooks ⇒ Object
Returns the list of after hooks.
-
.after_retries_exhausted(&block) ⇒ Object
Adds an after_retries_exhausted hook.
-
.after_retries_exhausted_hooks ⇒ Object
Returns the list of after_retries_exhausted hooks.
-
.around(&block) ⇒ Object
Adds an around hook Block receives (input, use_case, &block) where use_case allows access to dependencies.
-
.around_hooks ⇒ Object
Returns the list of around hooks.
-
.before(&block) ⇒ Object
Adds a before hook.
-
.before_hooks ⇒ Object
Returns the list of before hooks.
-
.before_retry(&block) ⇒ Object
Adds a before_retry hook.
-
.before_retry_hooks ⇒ Object
Returns the list of before_retry hooks.
-
.call(input = nil, container: nil, **args) ⇒ Object
Calls the UseCase with the given input.
-
.call!(input = nil, container: nil, **args) ⇒ Object
Calls the UseCase and captures any exceptions as failures.
-
.call_with_capture(input:, container: nil, exception_classes: [StandardError], code: :exception) ⇒ Object
Calls the UseCase with custom exception handling options.
-
.discard_matchers ⇒ Object
Returns the list of discard matchers.
-
.discard_on(*error_matchers) ⇒ Object
Configures errors that should immediately discard (no retry).
-
.extend_with(*extensions) ⇒ Object
Adds extension modules with hooks.
-
.extensions ⇒ Object
Returns the list of extensions.
- .inherited(subclass) ⇒ Object private
-
.input(*types) ⇒ Object
Declares the expected input type(s) for this UseCase Accepts a Class or one or more Modules that input must include.
-
.input_class ⇒ Object
Returns the input class (for backwards compatibility) If a Class is specified, returns it.
-
.input_types ⇒ Object
Returns the input types as an array.
-
.on_failure(&block) ⇒ Object
Adds an on_failure hook.
-
.on_failure_hooks ⇒ Object
Returns the list of on_failure hooks.
-
.on_failure_strategy ⇒ Object
Returns the failure handling strategy.
-
.organize(*use_case_classes, on_failure: :stop, &block) ⇒ Object
Declares a sequence of UseCases to execute as a pipeline.
-
.output(type_or_schema) ⇒ Object
Declares the expected output type for this UseCase.
-
.retry_configurations ⇒ Object
Returns the list of retry configurations.
-
.retry_on(*error_matchers, attempts: 3, wait: 0, backoff: :fixed, max_wait: nil, jitter: 0) ⇒ Object
Configures automatic retry for specific error types.
-
.step(use_case_class, if: nil, unless: nil, on_failure: nil, all: nil, any: nil, input: nil) ⇒ Object
Defines a step in the organize block.
Instance Method Summary collapse
-
#call(input = nil) ⇒ Object
Executes the UseCase logic.
-
#initialize(container: nil, dependencies: {}) ⇒ Base
constructor
Initializes the UseCase with dependencies resolved from the container.
-
#perform(input, capture_exceptions: false) ⇒ Object
Performs the UseCase with hooks.
Methods included from DependsOn
copy_depends_on_to, declared_namespace, dependencies, dependency_types, depends_on, extended, namespace
Constructor Details
#initialize(container: nil, dependencies: {}) ⇒ Base
Initializes the UseCase with dependencies resolved from the container
: (?container: Container?, ?dependencies: Hash[Symbol, untyped]) -> void
449 450 451 452 453 454 |
# File 'lib/senro_usecaser/base.rb', line 449 def initialize(container: nil, dependencies: {}) @_container = container || SenroUsecaser.container @_dependencies = {} #: Hash[Symbol, untyped] resolve_dependencies(@_container, dependencies) end |
Class Attribute Details
.organized_steps ⇒ Object (readonly)
Returns the list of organized steps
: () -> Array?
182 183 184 |
# File 'lib/senro_usecaser/base.rb', line 182 def organized_steps @organized_steps end |
.output_schema ⇒ Object (readonly)
Returns the output schema
: () -> (Class | Hash[Symbol, Class])?
389 390 391 |
# File 'lib/senro_usecaser/base.rb', line 389 def output_schema @output_schema end |
Class Method Details
.after(&block) ⇒ Object
Adds an after hook
: () { (untyped, Result) -> void } -> void
222 223 224 |
# File 'lib/senro_usecaser/base.rb', line 222 def after(&block) after_hooks << block end |
.after_hooks ⇒ Object
Returns the list of after hooks
: () -> Array
229 230 231 |
# File 'lib/senro_usecaser/base.rb', line 229 def after_hooks @after_hooks ||= [] end |
.after_retries_exhausted(&block) ⇒ Object
Adds an after_retries_exhausted hook
: () { (untyped, Result, RetryContext) -> void } -> void
332 333 334 |
# File 'lib/senro_usecaser/base.rb', line 332 def after_retries_exhausted(&block) after_retries_exhausted_hooks << block end |
.after_retries_exhausted_hooks ⇒ Object
Returns the list of after_retries_exhausted hooks
: () -> Array
339 340 341 |
# File 'lib/senro_usecaser/base.rb', line 339 def after_retries_exhausted_hooks @after_retries_exhausted_hooks ||= [] end |
.around(&block) ⇒ Object
237 238 239 |
# File 'lib/senro_usecaser/base.rb', line 237 def around(&block) around_hooks << block if block end |
.around_hooks ⇒ Object
Returns the list of around hooks
: () -> Array
244 245 246 |
# File 'lib/senro_usecaser/base.rb', line 244 def around_hooks @around_hooks ||= [] end |
.before(&block) ⇒ Object
Adds a before hook
: () { (untyped) -> void } -> void
208 209 210 |
# File 'lib/senro_usecaser/base.rb', line 208 def before(&block) before_hooks << block end |
.before_hooks ⇒ Object
Returns the list of before hooks
: () -> Array
215 216 217 |
# File 'lib/senro_usecaser/base.rb', line 215 def before_hooks @before_hooks ||= [] end |
.before_retry(&block) ⇒ Object
Adds a before_retry hook
: () { (untyped, Result, RetryContext) -> void } -> void
318 319 320 |
# File 'lib/senro_usecaser/base.rb', line 318 def before_retry(&block) before_retry_hooks << block end |
.before_retry_hooks ⇒ Object
Returns the list of before_retry hooks
: () -> Array
325 326 327 |
# File 'lib/senro_usecaser/base.rb', line 325 def before_retry_hooks @before_retry_hooks ||= [] end |
.call(input = nil, container: nil, **args) ⇒ Object
Calls the UseCase with the given input
: [T] (?untyped, ?container: Container, **untyped) -> Result
394 395 396 |
# File 'lib/senro_usecaser/base.rb', line 394 def call(input = nil, container: nil, **args) new(container: container).perform(input, capture_exceptions: false, **args) end |
.call!(input = nil, container: nil, **args) ⇒ Object
Calls the UseCase and captures any exceptions as failures
: [T] (?untyped, ?container: Container, **untyped) -> Result
401 402 403 404 405 |
# File 'lib/senro_usecaser/base.rb', line 401 def call!(input = nil, container: nil, **args) new(container: container).perform(input, capture_exceptions: true, **args) rescue StandardError => e Result.from_exception(e) end |
.call_with_capture(input:, container: nil, exception_classes: [StandardError], code: :exception) ⇒ Object
410 411 412 413 414 |
# File 'lib/senro_usecaser/base.rb', line 410 def call_with_capture(input:, container: nil, exception_classes: [StandardError], code: :exception) new(container: container).perform(input) rescue *exception_classes => e Result.from_exception(e, code: code) end |
.discard_matchers ⇒ Object
Returns the list of discard matchers
: () -> Array[(Symbol | Class)]
311 312 313 |
# File 'lib/senro_usecaser/base.rb', line 311 def discard_matchers @discard_matchers ||= [] end |
.discard_on(*error_matchers) ⇒ Object
Configures errors that should immediately discard (no retry)
: (*(Symbol | Class)) -> void
304 305 306 |
# File 'lib/senro_usecaser/base.rb', line 304 def discard_on(*error_matchers) discard_matchers.concat(error_matchers.flatten) end |
.extend_with(*extensions) ⇒ Object
Adds extension modules with hooks
: (*Module) -> void
194 195 196 |
# File 'lib/senro_usecaser/base.rb', line 194 def extend_with(*extensions) extensions.each { |ext| self.extensions << ext } end |
.extensions ⇒ Object
Returns the list of extensions
: () -> Array
201 202 203 |
# File 'lib/senro_usecaser/base.rb', line 201 def extensions @extensions ||= [] end |
.inherited(subclass) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
417 418 419 420 421 |
# File 'lib/senro_usecaser/base.rb', line 417 def inherited(subclass) super copy_configuration_to(subclass) copy_hooks_to(subclass) end |
.input(*types) ⇒ Object
Declares the expected input type(s) for this UseCase Accepts a Class or one or more Modules that input must include
: (*Module) -> void
356 357 358 |
# File 'lib/senro_usecaser/base.rb', line 356 def input(*types) @input_types = types end |
.input_class ⇒ Object
Returns the input class (for backwards compatibility) If a Class is specified, returns it. Otherwise returns the first type.
: () -> Module?
371 372 373 374 375 376 377 |
# File 'lib/senro_usecaser/base.rb', line 371 def input_class types = input_types return nil if types.empty? # Class があればそれを返す(単一 Class 指定の後方互換) types.find { |t| t.is_a?(Class) } || types.first end |
.input_types ⇒ Object
Returns the input types as an array
: () -> Array
363 364 365 |
# File 'lib/senro_usecaser/base.rb', line 363 def input_types @input_types || [] end |
.on_failure(&block) ⇒ Object
Adds an on_failure hook
: () { (untyped, Result, ?RetryContext?) -> void } -> void
251 252 253 |
# File 'lib/senro_usecaser/base.rb', line 251 def on_failure(&block) on_failure_hooks << block end |
.on_failure_hooks ⇒ Object
Returns the list of on_failure hooks
: () -> Array
258 259 260 |
# File 'lib/senro_usecaser/base.rb', line 258 def on_failure_hooks @on_failure_hooks ||= [] end |
.on_failure_strategy ⇒ Object
Returns the failure handling strategy
: () -> Symbol
187 188 189 |
# File 'lib/senro_usecaser/base.rb', line 187 def on_failure_strategy @on_failure_strategy || :stop end |
.organize(*use_case_classes, on_failure: :stop, &block) ⇒ Object
Declares a sequence of UseCases to execute as a pipeline
: (*Class, ?on_failure: Symbol) ?{ () -> void } -> void
145 146 147 148 149 150 151 152 153 154 155 156 |
# File 'lib/senro_usecaser/base.rb', line 145 def organize(*use_case_classes, on_failure: :stop, &block) @on_failure_strategy = on_failure if block @organized_steps = [] #: Array[Step] @_defining_steps = true instance_eval(&block) # steep:ignore BlockTypeMismatch @_defining_steps = false else @organized_steps = use_case_classes.map { |klass| Step.new(klass) } end end |
.output(type_or_schema) ⇒ Object
Declares the expected output type for this UseCase
: ((Class | Hash[Symbol, Class])) -> void
382 383 384 |
# File 'lib/senro_usecaser/base.rb', line 382 def output(type_or_schema) @output_schema = type_or_schema end |
.retry_configurations ⇒ Object
Returns the list of retry configurations
: () -> Array
291 292 293 |
# File 'lib/senro_usecaser/base.rb', line 291 def retry_configurations @retry_configurations ||= [] end |
.retry_on(*error_matchers, attempts: 3, wait: 0, backoff: :fixed, max_wait: nil, jitter: 0) ⇒ Object
Configures automatic retry for specific error types
rubocop:disable Metrics/ParameterLists : (*(Symbol | Class), ?attempts: Integer, ?wait: (Float | Integer), : ?backoff: Symbol, ?max_wait: (Float | Integer)?, ?jitter: (Float | Integer)) -> void
276 277 278 279 280 281 282 283 284 285 |
# File 'lib/senro_usecaser/base.rb', line 276 def retry_on(*error_matchers, attempts: 3, wait: 0, backoff: :fixed, max_wait: nil, jitter: 0) retry_configurations << RetryConfiguration.new( matchers: error_matchers.flatten, attempts: attempts, wait: wait, backoff: backoff, max_wait: max_wait, jitter: jitter ) end |
.step(use_case_class, if: nil, unless: nil, on_failure: nil, all: nil, any: nil, input: nil) ⇒ Object
Defines a step in the organize block
rubocop:disable Metrics/ParameterLists : (Class, ?if: (Symbol | Proc)?, ?unless: (Symbol | Proc)?, ?on_failure: Symbol?, : ?all: Array[(Symbol | Proc)]?, ?any: Array[(Symbol | Proc)]?, : ?input: (Symbol | Proc)?) -> void
164 165 166 167 168 169 170 171 172 173 174 175 176 |
# File 'lib/senro_usecaser/base.rb', line 164 def step(use_case_class, if: nil, unless: nil, on_failure: nil, all: nil, any: nil, input: nil) raise "step can only be called inside organize block" unless @_defining_steps @organized_steps << Step.new( use_case_class, if_condition: binding.local_variable_get(:if), unless_condition: binding.local_variable_get(:unless), on_failure: on_failure, all_conditions: all, any_conditions: any, input_mapping: input ) end |
Instance Method Details
#call(input = nil) ⇒ Object
Executes the UseCase logic
: (?untyped input) -> Result
473 474 475 476 477 |
# File 'lib/senro_usecaser/base.rb', line 473 def call(input = nil) return execute_pipeline(input) if self.class.organized_steps raise NotImplementedError, "#{self.class.name}#call must be implemented" end |
#perform(input, capture_exceptions: false) ⇒ Object
Performs the UseCase with hooks
: (untyped, ?capture_exceptions: bool) -> Result
459 460 461 462 463 464 465 466 467 468 |
# File 'lib/senro_usecaser/base.rb', line 459 def perform(input, capture_exceptions: false) @_capture_exceptions = capture_exceptions unless self.class.input_class || self.class.organized_steps raise ArgumentError, "#{self.class.name} must define `input` class" end validate_input!(input) execute_with_retry(input) end |