class ObjectFramework::Invocation
Executes a use case, detaches its result, and owns transaction cleanup. Applications normally enter this lifecycle through Application#invoke.
Public Class Methods
Source
# File lib/object_framework/execution.rb, line 135 def initialize(operation:, factories:, storage:, reporter:, mappings: nil) @operation, @factories, @storage, @reporter, @mappings = operation, factories, storage, reporter, mappings end
Public Instance Methods
Source
# File lib/object_framework/execution.rb, line 139 def call(context: ExecutionContext.new, **arguments) scope = Scope.new(@factories, context:) transaction = session = nil begin context.cancellation.check! if @operation.policy != :none transaction = if @storage.respond_to?(:begin_transaction_for) @storage.begin_transaction_for(mode: @operation.policy, context:) else @storage.begin_transaction(mode: @operation.policy) end context.transaction_state = :active scope.provide(:transaction, transaction) if @mappings session = Persistence::Session.new(transaction:, mappings: @mappings) scope.provide(:session, session) end end dependencies = @operation.dependencies.to_h { |name| [name, scope.resolve(name)] } use_case = @operation.use_case.new(**dependencies) result = Values.detach(use_case.call(**arguments)) context.cancellation.check! session&.flush if transaction context.transaction_state = :committing transaction.commit end context.transaction_state = :committed if transaction result rescue StandardError => error rollback(transaction, context:) @reporter.report(error, context:) raise ensure # Also release resources when a non-StandardError unwinds the request thread. rollback(transaction, context:) if context.transaction_state == :active session&.close scope.close(reporter: @reporter) close_transaction(transaction, context:) end end