Fork me on GitHub

Saturday, January 16, 2010

DNS lookup Experiment in Ruby - Blocking and NonBlocking Modes

Normal DNS lookup in Ruby (Blocking Mode)

require "resolv"

hosts = %w[www.yahoo.com www.google.com twitter.com github.com]

start = Time.now

hosts.each do |host|
p "Getting address for #{host}"
p Resolv.getaddress(host)
end

finish = Time.now

p "Time take to finish #{finish - start} seconds"


Execution Result -

"Getting address for www.yahoo.com"
"69.147.76.15"
"Getting address for www.google.com"
"209.85.231.104"
"Getting address for twitter.com"
"168.143.171.84"
"Getting address for github.com"
"207.97.227.239"
"Time take to finish 40.313232 seconds"

Non Blocking DNS Lookup in Ruby (Using EventMachine Deferrable)

require "rubygems"
require "resolv"
require "eventmachine"

class Dns
include EM::Deferrable
def resolve_hostname(hostname)
begin
ip = Resolv.getaddress(hostname)
set_deferred_status :succeeded, ip
rescue Exception => ex
set_deferred_status :failed, ex.to_s
end
end
end

start = Time.now
EventMachine.run {
p "Requesting DNS info for yahoo"
dns0 = Dns.new
dns0.callback {|response| p "For yahoo #{response}"}
dns0.errback {|response| p "For yahoo #{response}"}
Thread.new { dns0.resolve_hostname "www.yahoo.com"}

p "Requesting DNS info for google"
dns1 = Dns.new
dns1.callback {|response| p "For google #{response}"}
dns1.errback {|response| p "For google #{response}"}
Thread.new { dns1.resolve_hostname "www.google.com"}

p "Requesting DNS info for twitter"
dns2 = Dns.new
dns2.callback {|response| p "For twitter #{response}"}
dns2.errback {|response| p "For twitter #{response}"}
Thread.new { dns2.resolve_hostname "twitter.com"}

p "Requesting DNS info for github"
dns3 = Dns.new
dns3.callback {|response| p "For github #{response}"}
dns3.errback {|response| p "For github #{response}"}
Thread.new {dns3.resolve_hostname "github.com"; EM.stop }
}
finish = Time.now

p "Time take for querying #{finish - start} seconds"



Execution Result -

"Requesting DNS info for yahoo"
"Requesting DNS info for google"
"Requesting DNS info for twitter"
"Requesting DNS info for github"
"For google 209.85.231.99"
"For yahoo 69.147.76.15"
"For github 207.97.227.239"
"For twitter 128.121.146.100"
"Time take for querying 20.311271 seconds"

The results are obvious :). You can see the difference between the blocking and non blocking modes and the effect they may have on your systems. I am also planning to write a DNS library based on NeverBlock which uses Fibers as a way to do non blocking concurrency.

EventMachine is an excellent piece of software which gives a lot of functionality to do things asynchronously. Especially the Deferrable pattern is an awesome way to do long running jobs or calculations and still not block the whole world from running. I have been exploring EventMachine for sometime since I started writing em-couchdb.

The code is written in a simplified way and may not be of direct use to production but hope it reflects the principles of value of doing things in non blocking way.

No comments: