class Dry::Effects::Providers::Defer

Attributes

later_calls[R]
stack[R]

Public Instance Methods

call(options = {executor: Undefined}) { || ... } click to toggle source

Yield the block with the handler installed

@api private

# File lib/dry/effects/providers/defer.rb, line 54
def call(options = {executor: Undefined})
  unless Undefined.equal?(options[:executor])
    @executor = options[:executor]
  end

  @stack = Frame.stack
  @later_calls = []
  yield
ensure
  later_calls.each(&:execute)
end
defer(block, executor) click to toggle source
# File lib/dry/effects/providers/defer.rb, line 19
def defer(block, executor)
  stack = self.stack.dup
  at = Undefined.default(executor, self.executor)
  ::Concurrent::Promise.execute(executor: at) do
    Frame.spawn_fiber(stack, &block)
  end
end
dup() click to toggle source
Calls superclass method
# File lib/dry/effects/providers/defer.rb, line 66
def dup
  if defined? @later_calls
    super.tap { |p| p.instance_variable_set(:@later_calls, EMPTY_ARRAY) }
  else
    super
  end
end
later(block, executor) click to toggle source
# File lib/dry/effects/providers/defer.rb, line 27
        def later(block, executor)
          if @later_calls.frozen?
            Instructions.Raise(Errors::EffectRejectedError.new(<<~MSG))
              .later calls are not allowed, they would be processed
              by another stack. Add another defer handler to the current stack
            MSG
          else
            at = Undefined.default(executor, self.executor)
            stack = self.stack.dup
            @later_calls << ::Concurrent::Promise.new(executor: at) do
              Frame.spawn_fiber(stack, &block)
            end
            nil
          end
        end
represent() click to toggle source

@return [String] @api public

# File lib/dry/effects/providers/defer.rb, line 76
def represent
  info = []
  info << executor.to_s if executor.is_a?(::Symbol)
  info << "call_later=#{later_calls.size}" if later_calls.any?

  if info.empty?
    "defer"
  else
    "defer[#{info.join(" ")}]"
  end
end
wait(promises) click to toggle source
# File lib/dry/effects/providers/defer.rb, line 43
def wait(promises)
  if promises.is_a?(::Array)
    ::Concurrent::Promise.zip(*promises).value!
  else
    promises.value!
  end
end