Avoiding DNS delays with EventMachine::connect
Posted by alexd on Nov 21st, 2007
A concern with EventMachine has been potential blocking in the EventMachine::connect call, e.g. :
EventMachine::connect("dns-that-takes-ages.com", port, MyClass)
This call can block for a very long time, which is against the spirit of EventMachine. Fortunately, this problem can be solved using Dnsruby. A certain amount of boilerplate code is required here, which could be wrapped up in a new "EventMachine::connect_nonblock" call :
#boilerplate code
require 'Dnsruby'
require 'eventmachine'
res = Dnsruby::Resolver.new # use system defaults
Dnsruby::Resolver.use_eventmachine
Dnsruby::Resolver.start_eventmachine_loop(false)
#interesting code
#assumes EventMachine::run has been called
name = "dns_that_takes_ages.com"
df = res.send_async(Message.new(name))
df.callback {|msg|
EM.connect(msg.answer[0], 8289, MyClass) {}
}
df.errback {|msg, err|
print "Sorry - can't resolve #{name}. Error = #{err}n"
}
Now the call is non-blocking. If the DNS lookup succeeds, then the EM::connect call will continue as before. If the name can’t be resolved, then a different action is taken.

(4 votes, average: 4 out of 5)
August 7th, 2008 at 5:46 pm
Cool. This is something like the only way to avoid long DNS waits in Ruby. Others are: use rev, or require ‘resolv-replace’ I think is what it’s called.
Thanks!
-R