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 +1 -1
- data/examples/lookup_many.rb +55 -0
- data/lib/em/dns_cache.rb +74 -30
- metadata +4 -3
data/VERSION.yml
CHANGED
@@ -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
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
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
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
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
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
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
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
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
|
-
|
123
|
-
|
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.
|
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-
|
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:
|
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
|