Sha256: 5303869a330bd489f3f38ba4e2257ecc72491a5264ea33852cc1048ff90a8d2b

Contents?: true

Size: 1.32 KB

Versions: 3

Compression:

Stored size: 1.32 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) if fiber.alive?
          else
            results[index] = result
            fiber.resume(results.sort.map(&:last), nil) if
              results.size == funcs.size && fiber.alive?
          end
        })
    end
  end
end

Version data entries

3 entries across 3 versions & 1 rubygems

Version Path
sync-defer-0.9.6 lib/eventmachine/sync-defer.rb
sync-defer-0.9.5 lib/eventmachine/sync-defer.rb
sync-defer-0.9.4 lib/eventmachine/sync-defer.rb