astro-em-dns 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION.yml CHANGED
@@ -1,4 +1,4 @@
1
1
  ---
2
- :patch: 1
3
2
  :major: 0
4
3
  :minor: 0
4
+ :patch: 2
@@ -0,0 +1,55 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'uri'
4
+ require 'eventmachine'
5
+ $: << File.dirname(__FILE__) + '/../lib'
6
+ require 'em/dns_cache'
7
+
8
+ if ARGV.size == 0
9
+ puts "Usage: #{$0} <url-files>"
10
+ exit
11
+ end
12
+
13
+
14
+ hosts = []
15
+ ARGV.each do |fn|
16
+ IO::readlines(fn).each do |line|
17
+ line.chomp!
18
+ line.split(/\s+/).each do |url|
19
+ uri = URI::parse(url)
20
+ hosts << uri.host
21
+ end
22
+ end
23
+ end
24
+ puts "Will resolve #{hosts.size} hosts"
25
+
26
+ EM::DnsCache.add_nameservers_from_file
27
+ EM::DnsCache.verbose
28
+
29
+ EM.run {
30
+ pending = 0
31
+ hosts.each do |host|
32
+ df = EM::DnsCache.resolve(host)
33
+ df.callback { |*a|
34
+ if a.size == 1
35
+ if a.kind_of?(Array)
36
+ # Good!
37
+ else
38
+ p host => a[0]
39
+ end
40
+ else
41
+ p host => {:args => a}
42
+ end
43
+ pending -= 1
44
+ EM.stop if pending < 1
45
+ }
46
+ df.errback { |*a|
47
+ puts "Cannot resolve #{host}: #{a.inspect}"
48
+ pending -= 1
49
+ EM.stop if pending < 1
50
+ }
51
+ pending += 1
52
+ puts "#{pending} pending"
53
+ end
54
+ puts "Started all: #{pending} pending"
55
+ }
data/lib/em/dns_cache.rb CHANGED
@@ -35,6 +35,9 @@ module EventMachine
35
35
  @mx_cache = Cache.new
36
36
  @nameservers = []
37
37
  @message_ix = 0
38
+ MAX_WAITING = 20
39
+ @waiting = 0
40
+ @pending = []
38
41
 
39
42
  def self.add_nameserver ns
40
43
  @nameservers << ns unless @nameservers.include?(ns)
@@ -73,6 +76,8 @@ module EventMachine
73
76
  #
74
77
  def self.resolve domain
75
78
  if d = @a_cache.retrieve(domain)
79
+ puts "Cache hit for #{domain}" if @verbose
80
+ look_pending
76
81
  d
77
82
  else
78
83
  =begin
@@ -87,40 +92,79 @@ module EventMachine
87
92
  end
88
93
  else
89
94
  =end
90
- STDOUT.puts "Fulfilling #{domain} from network" if @verbose
91
- d = EM::DefaultDeferrable.new
92
- d.timeout(5)
93
- @a_cache.add domain, d, 300 # Hard-code a 5 minute expiration
94
- #@a_cache[domain] = [Time.now+120, d] # Hard code a 120-second expiration.
95
+ if @waiting >= MAX_WAITING
96
+ puts "Postponing #{domain} because already waiting for #{@waiting} queries" if @verbose
97
+ d = EM::DefaultDeferrable.new
98
+ @pending << lambda {
99
+ d_inner = resolve domain
100
+ d_inner.callback &d.method(:succeed)
101
+ d_inner.errback &d.method(:fail)
102
+ }
103
+ puts "#{@pending.size} pending requests now" if @verbose
104
+ d
105
+ else
106
+ d = resolve_do domain
107
+ @waiting += 1
108
+ STDOUT.puts "Now waiting for #{@waiting}" if @verbose
109
+ on_one_done = lambda {
110
+ @waiting -= 1
111
+ look_pending
112
+ }
113
+ d.callback &on_one_done
114
+ d.errback &on_one_done
115
+ d
116
+ end
117
+ end
118
+ end
95
119
 
96
- lazy_initialize
97
- m = Resolv::DNS::Message.new
98
- m.rd = 1
99
- m.add_question domain, Resolv::DNS::Resource::IN::A
100
- m = m.encode
101
- @nameservers.each {|ns|
102
- @message_ix = (@message_ix + 1) % 60000
103
- Request.new d, @message_ix
104
- msg = m.dup
105
- msg[0,2] = [@message_ix].pack("n")
106
- @u.send_datagram msg, ns, 53
107
- }
120
+ def self.look_pending
121
+ EM.next_tick {
122
+ while @waiting < MAX_WAITING && !@pending.empty?
123
+ pending1 = @pending.shift
124
+ pending1.call
125
+ puts "#{@pending.size} pending requests now" if @verbose
126
+ end
127
+ }
128
+ end
108
129
 
109
- d.callback {|resp|
110
- r = []
111
- resp.each_answer {|name,ttl,data|
112
- r << data.address.to_s if data.kind_of?(Resolv::DNS::Resource::IN::A)
113
- }
130
+ def self.resolve_do domain
131
+ STDOUT.puts "Fulfilling #{domain} from network" if @verbose
132
+ d = EM::DefaultDeferrable.new
133
+ d.timeout(5)
134
+ d.callback { d.cancel_timeout }
135
+ d.errback { d.cancel_timeout }
136
+ @a_cache.add domain, d, 300 # Hard-code a 5 minute expiration
137
+ #@a_cache[domain] = [Time.now+120, d] # Hard code a 120-second expiration.
138
+
139
+ lazy_initialize
140
+ m = Resolv::DNS::Message.new
141
+ m.rd = 1
142
+ m.add_question domain, Resolv::DNS::Resource::IN::A
143
+ m = m.encode
144
+ d_inner = EM::DefaultDeferrable.new
145
+ @nameservers.each {|ns|
146
+ @message_ix = (@message_ix + 1) % 60000
147
+ Request.new d_inner, @message_ix
148
+ msg = m.dup
149
+ msg[0,2] = [@message_ix].pack("n")
150
+ @u.send_datagram msg, ns, 53
151
+ }
114
152
 
115
- # Freeze the array since we'll be keeping it in cache and passing it
116
- # around to multiple users. And alternative would have been to dup it.
117
- r.freeze
118
- d.succeed r
153
+ d_inner.callback {|resp|
154
+ r = []
155
+ resp.each_answer {|name,ttl,data|
156
+ r << data.address.to_s if data.kind_of?(Resolv::DNS::Resource::IN::A)
119
157
  }
120
158
 
159
+ # Freeze the array since we'll be keeping it in cache and passing it
160
+ # around to multiple users. And alternative would have been to dup it.
161
+ r.freeze
162
+ d.succeed r
163
+ }
164
+ d_inner.errback &d.method(:fail)
121
165
 
122
- d
123
- end
166
+
167
+ d
124
168
  end
125
169
 
126
170
 
@@ -275,8 +319,8 @@ module EventMachine
275
319
  @@outstanding[@msgid] = self
276
320
 
277
321
  self.timeout(10)
278
- self.errback { @@outstanding.delete(@msgid) }
279
- self.callback {|resp| @result.succeed resp }
322
+ self.errback { self.cancel_timeout; @@outstanding.delete(@msgid); @result.fail }
323
+ self.callback {|resp| self.cancel_timeout; @result.succeed resp }
280
324
  end
281
325
  end
282
326
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: astro-em-dns
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aman Gupta
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2009-05-17 00:00:00 -07:00
13
+ date: 2009-05-19 00:00:00 -07:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -36,7 +36,7 @@ files:
36
36
  - VERSION.yml
37
37
  - lib/em/dns_cache.rb
38
38
  - test/test_basic.rb
39
- has_rdoc: true
39
+ has_rdoc: false
40
40
  homepage: http://github.com/astro/em-dns
41
41
  post_install_message:
42
42
  rdoc_options:
@@ -64,3 +64,4 @@ specification_version: 3
64
64
  summary: Resolve domain names from EventMachine natively
65
65
  test_files:
66
66
  - test/test_basic.rb
67
+ - examples/lookup_many.rb