Sha256: 5f601a52ff4e308a5bea5db35d817f2f935426e6a91794d13ecfbdeeb71dd287
Contents?: true
Size: 1.88 KB
Versions: 2
Compression:
Stored size: 1.88 KB
Contents
# frozen_string_literal: true require 'fiber' require 'dry/effects/initializer' require 'dry/effects/effect' require 'dry/effects/errors' require 'dry/effects/stack' require 'dry/effects/instructions/raise' module Dry module Effects # Stack frame # # @api private class Frame class << self # Accessing current stack of effect handlers. # It is inherently thread/fiber-local. # # @return [Stack] # @api private def stack ::Thread.current[:dry_effects_stack] ||= Stack.new end # @param [Stack] stack # @api private def stack=(stack) ::Thread.current[:dry_effects_stack] = stack end # Spawn a new fiber with a stack of effect handlers # # @param [Stack] stack # @api private def spawn_fiber(stack) fiber = ::Fiber.new do self.stack = stack yield end result = fiber.resume loop do break result unless fiber.alive? provided = stack.(result) do ::Dry::Effects.yield(result) do |_, error| Instructions.Raise(error) end end result = fiber.resume(provided) end end end extend Initializer # @!attribute provider # @return [Provider] Effects provider param :provider # Add new handler to the current stack # and run the given block # # @param [Array<Object>] args Handler arguments # @param [Proc] block Program to run # @api private def call(args = EMPTY_ARRAY, &block) stack = Frame.stack if stack.empty? stack.push(provider.dup, args) { Frame.spawn_fiber(stack, &block) } else stack.push(provider.dup, args, &block) end end end end end
Version data entries
2 entries across 2 versions & 1 rubygems
Version | Path |
---|---|
dry-effects-0.1.1 | lib/dry/effects/frame.rb |
dry-effects-0.1.0 | lib/dry/effects/frame.rb |