def process_callbacks(event_type, event_data)
      @callbacks[event_type].each do |callback|
        fiber = Fiber.new do
          begin
            callback.call(event_data)
          rescue => e
            @loggers.error "-- #{e.class}: #{e.message}"
            e.backtrace.each { |line| @loggers.error("-- #{line}") }
          end
        end

        # If the callback has a :defer option, call it in a thread
        # from the EM thread pool. Else call it in the reactor thread.
        if callback.options[:defer]
          EM.defer(fiber.resume)
        else
          fiber.resume
        end
      end
    end
def process_callbacks(event_type, event_data)
      @callbacks[event_type].each do |callback|
        fiber = Fiber.new do
          begin
            callback.call(event_data)
          rescue => e
            @loggers.error "-- #{e.class}: #{e.message}"
            e.backtrace.each { |line| @loggers.error("-- #{line}") }
          end
        end

        # If the callback has a :defer option, call it in a thread
        # from the EM thread pool. Else call it in the reactor thread.
        if callback.options[:defer]
          EM.defer(fiber.resume)
        else
          fiber.resume
        end
      end
    end
Each matching callback will run in its own fiber. So the execution
 of code can be stopped until necessary data (eg from a WHOIS) gets in.

 The callback processing is exception handled, so the EM reactor won't die
 from exceptions.