unbound 1.0.1 → 2.0.0
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.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/lib/unbound/context.rb +8 -1
- data/lib/unbound/query.rb +1 -0
- data/lib/unbound/resolver.rb +10 -7
- data/spec/context_spec.rb +27 -0
- data/spec/query_spec.rb +47 -0
- data/spec/query_store_spec.rb +14 -0
- data/spec/resolver_spec.rb +94 -26
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3cc064fa99fcaf867d9474ede41d93ad258742e4
|
|
4
|
+
data.tar.gz: dd0dd181466af047705bb39f94db521141eaa752
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 51c16931c919a0635208f7ec37f4820f5a7b53e9ec7de05d34f8f0c52d0496dd3e2be8684bf7ac3fedf0cb91565d8c9a14076885b789efd91eda13efbb708f81
|
|
7
|
+
data.tar.gz: b24c0751df53c3e44418db0c85de1b8678c9bd0f0a6180511316ba88adcf39bb17c499a458927661a38b6d5545b8fd9cc0bee76249a37ce59fdbdadbec9e67f1
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
2.0.0
|
data/lib/unbound/context.rb
CHANGED
|
@@ -71,10 +71,17 @@ module Unbound
|
|
|
71
71
|
raise_if_error!(Unbound::Bindings.ub_cancel(@ub_ctx, async_id))
|
|
72
72
|
end
|
|
73
73
|
|
|
74
|
+
# Returns a brand new IO for the file descriptor that can be selected to
|
|
75
|
+
# determine if processing needs to be done.
|
|
76
|
+
# Warning: DO NOT CLOSE THIS IO OBJECT! Use Context#close, instead.
|
|
77
|
+
# @return [FFI::IO] a brand new IO for the context's file descriptor
|
|
74
78
|
def io
|
|
75
|
-
|
|
79
|
+
ret = ::FFI::IO.for_fd(self.fd)
|
|
80
|
+
ret.autoclose = false
|
|
81
|
+
return ret
|
|
76
82
|
end
|
|
77
83
|
|
|
84
|
+
# Returns the number for the file descriptor.
|
|
78
85
|
def fd
|
|
79
86
|
check_closed!
|
|
80
87
|
Unbound::Bindings.ub_fd(@ub_ctx)
|
data/lib/unbound/query.rb
CHANGED
data/lib/unbound/resolver.rb
CHANGED
|
@@ -20,16 +20,18 @@ module Unbound
|
|
|
20
20
|
|
|
21
21
|
init_callbacks
|
|
22
22
|
|
|
23
|
-
on_cancel do |query|
|
|
24
|
-
if query.async_id
|
|
25
|
-
@ctx.cancel_async_query(query.async_id)
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
23
|
on_finish do |query|
|
|
29
24
|
@queries.delete_query(query)
|
|
30
25
|
end
|
|
31
26
|
end
|
|
32
27
|
|
|
28
|
+
# @param [Unbound::Query] query The query that will be canceled
|
|
29
|
+
def cancel_query(query)
|
|
30
|
+
return if query.async_id.nil?
|
|
31
|
+
@ctx.cancel_async_query(query.async_id)
|
|
32
|
+
query.cancel!
|
|
33
|
+
end
|
|
34
|
+
|
|
33
35
|
# @return [Integer] the number of queries for which we are awaiting reply
|
|
34
36
|
def outstanding_queries
|
|
35
37
|
@queries.count
|
|
@@ -63,7 +65,7 @@ module Unbound
|
|
|
63
65
|
# Cancel all outstanding queries.
|
|
64
66
|
def cancel_all
|
|
65
67
|
@queries.each do |query|
|
|
66
|
-
query
|
|
68
|
+
cancel_query(query)
|
|
67
69
|
end
|
|
68
70
|
@queries.clear
|
|
69
71
|
end
|
|
@@ -98,7 +100,8 @@ module Unbound
|
|
|
98
100
|
query.on_start(*@callbacks_start) unless @callbacks_start.empty?
|
|
99
101
|
query.on_answer(*@callbacks_answer) unless @callbacks_answer.empty?
|
|
100
102
|
query.on_error(*@callbacks_error) unless @callbacks_error.empty?
|
|
101
|
-
query.on_cancel(*@callbacks_cancel)
|
|
103
|
+
query.on_cancel(*@callbacks_cancel) unless @callbacks_cancel.empty?
|
|
104
|
+
|
|
102
105
|
query.on_finish(*@callbacks_finish)
|
|
103
106
|
ptr = @queries.store(query)
|
|
104
107
|
async_id = @ctx.resolve_async(
|
data/spec/context_spec.rb
CHANGED
|
@@ -139,6 +139,33 @@ describe Unbound::Context do
|
|
|
139
139
|
end
|
|
140
140
|
end
|
|
141
141
|
|
|
142
|
+
describe "#io" do
|
|
143
|
+
it "should return an IO object" do
|
|
144
|
+
expect(@ctx.io).to be_a(::IO)
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
it "should return a new IO object for each call" do
|
|
148
|
+
expect(@ctx.io).not_to be(@ctx.io)
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
it "should not be set to autoclose" do
|
|
152
|
+
expect(@ctx.io.autoclose?).to be_false
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
it "should not autoclose when garbage collection occurs" do
|
|
156
|
+
do_gc = lambda { ObjectSpace.garbage_collect }
|
|
157
|
+
|
|
158
|
+
if Object.const_defined?(:JRuby)
|
|
159
|
+
# Try to get some GC under JRuby
|
|
160
|
+
do_gc = lambda { java.lang.System.gc() }
|
|
161
|
+
end
|
|
162
|
+
::IO::select([@ctx.io], nil, nil, 0)
|
|
163
|
+
do_gc.call()
|
|
164
|
+
expect {
|
|
165
|
+
::IO::select([@ctx.io], nil, nil, 0)
|
|
166
|
+
}.not_to raise_error
|
|
167
|
+
end
|
|
168
|
+
end
|
|
142
169
|
|
|
143
170
|
describe "asynchronous query processing via select/process" do
|
|
144
171
|
before :each do
|
data/spec/query_spec.rb
CHANGED
|
@@ -33,6 +33,22 @@ describe Unbound::Query do
|
|
|
33
33
|
end
|
|
34
34
|
end
|
|
35
35
|
|
|
36
|
+
describe "#async_id" do
|
|
37
|
+
it "should be nil if the query hasn't been started" do
|
|
38
|
+
expect(@query.async_id).to be_nil
|
|
39
|
+
end
|
|
40
|
+
it "should be the proper value if it has been started" do
|
|
41
|
+
expect(@query.async_id).to be_nil
|
|
42
|
+
@query.start!(1234)
|
|
43
|
+
expect(@query.async_id).to eq(1234)
|
|
44
|
+
end
|
|
45
|
+
it "should be nil if the query has been finished" do
|
|
46
|
+
@query.start!(1234)
|
|
47
|
+
@query.cancel!
|
|
48
|
+
expect(@query.async_id).to be_nil
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
36
52
|
describe "#start!" do
|
|
37
53
|
it "should set the async_id" do
|
|
38
54
|
expect(@query.async_id).to be_nil
|
|
@@ -66,6 +82,11 @@ describe Unbound::Query do
|
|
|
66
82
|
end
|
|
67
83
|
|
|
68
84
|
describe "#error!" do
|
|
85
|
+
before :each do
|
|
86
|
+
@async_id = 9999
|
|
87
|
+
@query.start!(@async_id)
|
|
88
|
+
end
|
|
89
|
+
|
|
69
90
|
it "should require an error code as an argument" do
|
|
70
91
|
expect {
|
|
71
92
|
@query.error!
|
|
@@ -79,9 +100,19 @@ describe Unbound::Query do
|
|
|
79
100
|
@query.error!(1234)
|
|
80
101
|
expect(@query).to be_finished
|
|
81
102
|
end
|
|
103
|
+
|
|
104
|
+
it "should have set async_id to nil" do
|
|
105
|
+
@query.error!(1234)
|
|
106
|
+
expect(@query.async_id).to be_nil
|
|
107
|
+
end
|
|
82
108
|
end
|
|
83
109
|
|
|
84
110
|
describe "#answer!" do
|
|
111
|
+
before :each do
|
|
112
|
+
@async_id = 9999
|
|
113
|
+
@query.start!(@async_id)
|
|
114
|
+
end
|
|
115
|
+
|
|
85
116
|
it "should require a result as an argument" do
|
|
86
117
|
expect {
|
|
87
118
|
@query.answer!
|
|
@@ -97,9 +128,20 @@ describe Unbound::Query do
|
|
|
97
128
|
@query.answer!(result)
|
|
98
129
|
expect(@query).to be_finished
|
|
99
130
|
end
|
|
131
|
+
|
|
132
|
+
it "should have set async_id to nil" do
|
|
133
|
+
result = double("Result")
|
|
134
|
+
@query.answer!(result)
|
|
135
|
+
expect(@query.async_id).to be_nil
|
|
136
|
+
end
|
|
100
137
|
end
|
|
101
138
|
|
|
102
139
|
describe "#cancel!" do
|
|
140
|
+
before :each do
|
|
141
|
+
@async_id = 9999
|
|
142
|
+
@query.start!(@async_id)
|
|
143
|
+
end
|
|
144
|
+
|
|
103
145
|
it "should require that no arguments be specified" do
|
|
104
146
|
expect {
|
|
105
147
|
@query.cancel!(1234)
|
|
@@ -113,6 +155,11 @@ describe Unbound::Query do
|
|
|
113
155
|
@query.cancel!
|
|
114
156
|
expect(@query).to be_finished
|
|
115
157
|
end
|
|
158
|
+
|
|
159
|
+
it "should have set async_id to nil" do
|
|
160
|
+
@query.cancel!
|
|
161
|
+
expect(@query.async_id).to be_nil
|
|
162
|
+
end
|
|
116
163
|
end
|
|
117
164
|
|
|
118
165
|
|
data/spec/query_store_spec.rb
CHANGED
|
@@ -29,6 +29,20 @@ describe Unbound::QueryStore do
|
|
|
29
29
|
end
|
|
30
30
|
expect(actual_queries).to match_array(expected_queries)
|
|
31
31
|
end
|
|
32
|
+
it "should not yield deleted queries" do
|
|
33
|
+
q1 = new_query(1)
|
|
34
|
+
q2 = new_query(2)
|
|
35
|
+
q3 = new_query(3)
|
|
36
|
+
query_store.store(q1)
|
|
37
|
+
query_store.store(q2)
|
|
38
|
+
query_store.store(q3)
|
|
39
|
+
query_store.delete_query(q2)
|
|
40
|
+
remaining_queries = []
|
|
41
|
+
query_store.each do |query|
|
|
42
|
+
remaining_queries << query
|
|
43
|
+
end
|
|
44
|
+
expect(remaining_queries).to match_array([q1, q3])
|
|
45
|
+
end
|
|
32
46
|
end
|
|
33
47
|
describe "#clear" do
|
|
34
48
|
it "should cause the count to drop to 0" do
|
data/spec/resolver_spec.rb
CHANGED
|
@@ -9,29 +9,71 @@ describe Unbound::Resolver do
|
|
|
9
9
|
after :each do
|
|
10
10
|
@resolver.close unless @resolver.closed?
|
|
11
11
|
end
|
|
12
|
+
|
|
13
|
+
let(:query) { Unbound::Query.new("localhost", 1, 1) }
|
|
12
14
|
|
|
13
15
|
describe "#cancel_all" do
|
|
14
16
|
it "should cancel all queries" do
|
|
15
|
-
query1 = Unbound::Query.new("localhost", 1, 1)
|
|
16
17
|
expect { |cb|
|
|
17
|
-
|
|
18
|
-
@resolver.send_query(
|
|
18
|
+
query.on_cancel(cb.to_proc)
|
|
19
|
+
@resolver.send_query(query)
|
|
19
20
|
@resolver.cancel_all
|
|
20
21
|
}.to yield_control
|
|
21
22
|
end
|
|
22
23
|
end
|
|
23
24
|
|
|
24
25
|
describe "#outstanding_queries" do
|
|
25
|
-
it "should
|
|
26
|
+
it "should be zero if there are no queries" do
|
|
26
27
|
expect(@resolver.outstanding_queries).to eq(0)
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it "should go up by one for each query added" do
|
|
31
|
+
q1 = Unbound::Query.new("localhost", 1, 1)
|
|
32
|
+
q2 = Unbound::Query.new("localhost", 1, 1)
|
|
33
|
+
q3 = Unbound::Query.new("localhost", 1, 1)
|
|
34
|
+
q4 = Unbound::Query.new("localhost", 1, 1)
|
|
35
|
+
expect(@resolver.outstanding_queries).to eq(0)
|
|
36
|
+
@resolver.send_query(q1)
|
|
37
|
+
expect(@resolver.outstanding_queries).to eq(1)
|
|
38
|
+
@resolver.send_query(q2)
|
|
39
|
+
expect(@resolver.outstanding_queries).to eq(2)
|
|
40
|
+
@resolver.send_query(q3)
|
|
41
|
+
expect(@resolver.outstanding_queries).to eq(3)
|
|
42
|
+
@resolver.send_query(q4)
|
|
43
|
+
expect(@resolver.outstanding_queries).to eq(4)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it "should drop by one for each query canceled" do
|
|
47
|
+
q1 = Unbound::Query.new("localhost", 1, 1)
|
|
48
|
+
q2 = Unbound::Query.new("localhost", 1, 1)
|
|
49
|
+
q3 = Unbound::Query.new("localhost", 1, 1)
|
|
50
|
+
q4 = Unbound::Query.new("localhost", 1, 1)
|
|
51
|
+
@resolver.send_query(q1)
|
|
52
|
+
@resolver.send_query(q2)
|
|
53
|
+
@resolver.send_query(q3)
|
|
54
|
+
@resolver.send_query(q4)
|
|
55
|
+
expect(@resolver.outstanding_queries).to eq(4)
|
|
56
|
+
@resolver.cancel_query(q1)
|
|
57
|
+
expect(@resolver.outstanding_queries).to eq(3)
|
|
58
|
+
@resolver.cancel_query(q2)
|
|
59
|
+
expect(@resolver.outstanding_queries).to eq(2)
|
|
60
|
+
@resolver.cancel_query(q3)
|
|
61
|
+
expect(@resolver.outstanding_queries).to eq(1)
|
|
62
|
+
@resolver.cancel_query(q4)
|
|
33
63
|
expect(@resolver.outstanding_queries).to eq(0)
|
|
34
64
|
end
|
|
65
|
+
|
|
66
|
+
it "should not reduce the count by more than one if the same query is canceled twice" do
|
|
67
|
+
q1 = Unbound::Query.new("localhost", 1, 1)
|
|
68
|
+
q2 = Unbound::Query.new("localhost", 1, 1)
|
|
69
|
+
@resolver.send_query(q1)
|
|
70
|
+
@resolver.send_query(q2)
|
|
71
|
+
expect(@resolver.outstanding_queries).to eq(2)
|
|
72
|
+
@resolver.cancel_query(q1)
|
|
73
|
+
expect(@resolver.outstanding_queries).to eq(1)
|
|
74
|
+
@resolver.cancel_query(q1)
|
|
75
|
+
expect(@resolver.outstanding_queries).to eq(1)
|
|
76
|
+
end
|
|
35
77
|
end
|
|
36
78
|
|
|
37
79
|
describe "#outstanding_queries?" do
|
|
@@ -40,7 +82,6 @@ describe Unbound::Resolver do
|
|
|
40
82
|
end
|
|
41
83
|
|
|
42
84
|
it "should be true if there are any outstanding queries" do
|
|
43
|
-
query = Unbound::Query.new("localhost", 1, 1)
|
|
44
85
|
@resolver.send_query(query)
|
|
45
86
|
expect(@resolver.outstanding_queries?).to be_true
|
|
46
87
|
end
|
|
@@ -69,17 +110,20 @@ describe Unbound::Resolver do
|
|
|
69
110
|
end
|
|
70
111
|
|
|
71
112
|
describe "#io" do
|
|
72
|
-
it "should
|
|
73
|
-
|
|
113
|
+
it "should pass through to ctx.io" do
|
|
114
|
+
ctx = double("Context")
|
|
115
|
+
resolver = Unbound::Resolver.new(ctx)
|
|
116
|
+
expect(ctx).to receive(:io)
|
|
117
|
+
resolver.io
|
|
74
118
|
end
|
|
119
|
+
|
|
75
120
|
end
|
|
76
121
|
|
|
77
122
|
describe "#process" do
|
|
78
123
|
it "should call our callback" do
|
|
79
|
-
query1 = Unbound::Query.new("localhost", 1, 1)
|
|
80
124
|
expect { |cb|
|
|
81
|
-
|
|
82
|
-
@resolver.send_query(
|
|
125
|
+
query.on_answer(cb.to_proc)
|
|
126
|
+
@resolver.send_query(query)
|
|
83
127
|
io = @resolver.io
|
|
84
128
|
expect(::IO.select([io], nil, nil, 5)).to_not be_nil
|
|
85
129
|
@resolver.process
|
|
@@ -87,17 +131,45 @@ describe Unbound::Resolver do
|
|
|
87
131
|
end
|
|
88
132
|
end
|
|
89
133
|
|
|
134
|
+
describe "#cancel_query" do
|
|
135
|
+
it "should all context#cancel_async_query" do
|
|
136
|
+
expect(@context).to receive(:cancel_async_query).and_call_original
|
|
137
|
+
@resolver.send_query(query)
|
|
138
|
+
@resolver.cancel_query(query)
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
it "should set query.async_id to nil" do
|
|
142
|
+
@resolver.send_query(query)
|
|
143
|
+
expect(query.async_id).not_to be_nil
|
|
144
|
+
@resolver.cancel_query(query)
|
|
145
|
+
expect(query.async_id).to be_nil
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
it "should call 'query#cancel!' only once" do
|
|
149
|
+
@resolver.send_query(query)
|
|
150
|
+
expect(query).to receive(:cancel!).exactly(1).times.and_call_original
|
|
151
|
+
@resolver.cancel_query(query)
|
|
152
|
+
@resolver.close
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
it "shouldn't try to cancel if the query hasn't been sent" do
|
|
156
|
+
query = double("Query")
|
|
157
|
+
allow(query).to receive(:async_id).and_return(nil)
|
|
158
|
+
ctx = double("Context")
|
|
159
|
+
resolver = Unbound::Resolver.new(ctx)
|
|
160
|
+
resolver.cancel_query(query)
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
|
|
90
164
|
describe "#send_query" do
|
|
91
165
|
it "should raise an exception if the same query object is submitted twice" do
|
|
92
|
-
|
|
93
|
-
@resolver.send_query(
|
|
94
|
-
expect {@resolver.send_query(query1)}.to raise_error
|
|
166
|
+
@resolver.send_query(query)
|
|
167
|
+
expect {@resolver.send_query(query)}.to raise_error
|
|
95
168
|
end
|
|
96
169
|
end
|
|
97
170
|
|
|
98
171
|
describe "#on_start" do
|
|
99
172
|
specify "callbacks should be called when send_query is called" do
|
|
100
|
-
query = Unbound::Query.new("localhost", 1, 1)
|
|
101
173
|
expect { |cb|
|
|
102
174
|
@resolver.on_start(&cb)
|
|
103
175
|
@resolver.send_query(query)
|
|
@@ -107,7 +179,6 @@ describe Unbound::Resolver do
|
|
|
107
179
|
|
|
108
180
|
describe "#on_answer" do
|
|
109
181
|
specify "callbacks should be called if the query has been answered" do
|
|
110
|
-
query = Unbound::Query.new("localhost", 1, 1)
|
|
111
182
|
result = double("Result")
|
|
112
183
|
expect { |cb|
|
|
113
184
|
@resolver.on_answer(&cb)
|
|
@@ -119,7 +190,6 @@ describe Unbound::Resolver do
|
|
|
119
190
|
|
|
120
191
|
describe "#on_error" do
|
|
121
192
|
specify "callbacks should be called if the query has an error" do
|
|
122
|
-
query = Unbound::Query.new("localhost", 1, 1)
|
|
123
193
|
result = double("Result")
|
|
124
194
|
expect { |cb|
|
|
125
195
|
@resolver.on_error(&cb)
|
|
@@ -131,24 +201,22 @@ describe Unbound::Resolver do
|
|
|
131
201
|
|
|
132
202
|
describe "#on_cancel" do
|
|
133
203
|
specify "callbacks should be called if the query has been canceled" do
|
|
134
|
-
query = Unbound::Query.new("localhost", 1, 1)
|
|
135
204
|
result = double("Result")
|
|
136
205
|
expect { |cb|
|
|
137
206
|
@resolver.on_cancel(&cb)
|
|
138
207
|
@resolver.send_query(query)
|
|
139
|
-
|
|
208
|
+
@resolver.cancel_query(query)
|
|
140
209
|
}.to yield_with_args(query)
|
|
141
210
|
end
|
|
142
211
|
end
|
|
143
212
|
|
|
144
213
|
describe "#on_finish" do
|
|
145
214
|
specify "callbacks should be called if the query is finished for any reason" do
|
|
146
|
-
query = Unbound::Query.new("localhost", 1, 1)
|
|
147
215
|
result = double("Result")
|
|
148
216
|
expect { |cb|
|
|
149
217
|
@resolver.on_finish(&cb)
|
|
150
218
|
@resolver.send_query(query)
|
|
151
|
-
|
|
219
|
+
@resolver.cancel_query(query)
|
|
152
220
|
}.to yield_with_args(query)
|
|
153
221
|
end
|
|
154
222
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: unbound
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 2.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Mike Ryan
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2014-03-
|
|
11
|
+
date: 2014-03-12 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: ffi
|