lib/em-whois.rb in em-whois-0.1.1 vs lib/em-whois.rb in em-whois-0.2.0

- old
+ new

@@ -2,51 +2,56 @@ require 'em-synchrony' module Whois class Server module Adapters + class Base + private - # This method handles the lowest connection - # to the WHOIS server. # - # This is for internal use only! + # Overwrite Whois::Server::Adapters::Base#ask_the_socket to + # be EventMachine-aware, and send calls offs asynchronously + # if the EM reactor is running, otherwise fallback to the + # synchronous connection. # - # @api internal alias :orig_ask_the_socket :ask_the_socket def ask_the_socket(*args) defined?(EM) && EM.reactor_running? ? em_ask_the_socket(*args) : orig_ask_the_socket(*args) end # ask_the_socket def em_ask_the_socket(query, *args) - client = EventMachine::Synchrony::TCPSocket.new(*args) - client.write("#{query}\r\n") # I could use put(foo) and forget the \n - # but write/read is more symmetric than puts/read - # and I really want to use read instead of gets. + fiber = Fiber.current + EM::connect args[0], args[1], AsyncClient, query, fiber + Fiber.yield + end # em_ask_the_socket - response = "" + end # Base - # Synchrony TCPSocket behaves a little differently, seems to require - # polling until an IO exception is thrown. - # TODO: There's gotta be a more elegant way to achieve this. - while true do - begin - response += client.read - rescue IOError => e - break - end - end + class AsyncClient < EventMachine::Connection - response + def initialize *args + @query, @fiber = args[0..1] + @data = "" + super + end - ensure - client.close if client # If != client something went wrong. - - end # em_ask_the_socket + def post_init + send_data "#{@query}\r\n" + end - end + def receive_data(data) + @data << data + end + + def unbind + @fiber.resume @data + end + + end # AsyncClient + end end end