Sha256: 4676ae613b6ba4ba1a8b49c037f0ea1597c9a82367cfb042fe5fd86bb82ce7e5

Contents?: true

Size: 1.29 KB

Versions: 2

Compression:

Stored size: 1.29 KB

Contents

require 'fiber'
require 'eventmachine'

module EventMachine::SyncDefer
  module_function
  def defer *funcs, &block
    fiber = Fiber.current
    funcs << block if block_given?
    if funcs.size == 1
      defer_one(fiber, funcs.first)
    else
      defer_multi(fiber, funcs)
    end
    result, exception = Fiber.yield
    if exception
      raise exception
    else
      result
    end
  end

  def defer_one fiber, func
    exception = nil
    EventMachine.defer(lambda{
                         begin
                           func.call
                         rescue Exception => e
                           exception = e
                         end
                       },
                       lambda{ |result| fiber.resume(result, exception)})
  end

  def defer_multi fiber, funcs
    results, exception = {}, nil
    funcs.each.with_index do |func, index|
      EventMachine.defer(
        lambda{
          begin
            func.call
          rescue Exception => e
            exception = e
          end
        },
        lambda{ |result|
          if exception
            fiber.resume(nil, exception)
          else
            results[index] = result
            fiber.resume(results.sort.map(&:last), nil) if
              results.size == funcs.size
          end
        })
    end
  end
end

Version data entries

2 entries across 2 versions & 1 rubygems

Version Path
sync-defer-0.9.3 lib/eventmachine/sync-defer.rb
sync-defer-0.9.2 lib/eventmachine/sync-defer.rb