Sha256: 510bc8bdb7c151bdeb046766c0d53b63f9e19f099b7d49c17b21b4ef6ea9e902

Contents?: true

Size: 1.24 KB

Versions: 2

Compression:

Stored size: 1.24 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
    class Handler
      class << self
        def stack
          ::Thread.current[:dry_effects_stack] ||= Stack.new
        end

        def stack=(stack)
          ::Thread.current[:dry_effects_stack] = stack
        end

        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

      param :provider

      def call(args = EMPTY_ARRAY, &block)
        stack = Handler.stack

        if stack.empty?
          stack.push(provider.dup, args) { Handler.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.0.alpha2 lib/dry/effects/handler.rb
dry-effects-0.1.0.alpha lib/dry/effects/handler.rb