astro-em-dns 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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