agent 0.1.0 → 0.9.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.
- data/.gitignore +2 -0
- data/.rspec +0 -0
- data/Gemfile +0 -1
- data/Gemfile.lock +12 -12
- data/README.md +51 -36
- data/Rakefile +5 -0
- data/agent.gemspec +1 -0
- data/autotest/discover.rb +9 -1
- data/benchmark/multi_ruby_bench.sh +87 -0
- data/benchmark/sieve.rb +238 -0
- data/examples/agent-workers.rb +51 -0
- data/examples/producer-consumer.rb +15 -0
- data/lib/agent.rb +1 -15
- data/lib/agent/all.rb +22 -0
- data/lib/agent/blocking_once.rb +26 -0
- data/lib/agent/channel.rb +88 -41
- data/lib/agent/error.rb +15 -0
- data/lib/agent/errors.rb +14 -0
- data/lib/agent/go.rb +9 -0
- data/lib/agent/kernel/channel.rb +7 -0
- data/lib/agent/kernel/go.rb +7 -0
- data/lib/agent/kernel/select.rb +7 -0
- data/lib/agent/notifier.rb +34 -0
- data/lib/agent/once.rb +32 -0
- data/lib/agent/pop.rb +70 -0
- data/lib/agent/push.rb +70 -0
- data/lib/agent/queue.rb +133 -0
- data/lib/agent/queue/buffered.rb +68 -0
- data/lib/agent/queue/unbuffered.rb +88 -0
- data/lib/agent/queues.rb +50 -0
- data/lib/agent/selector.rb +119 -0
- data/lib/agent/uuid.rb +36 -0
- data/lib/agent/version.rb +1 -1
- data/lib/agent/wait_group.rb +43 -0
- data/spec/blocking_once_spec.rb +122 -0
- data/spec/channel_spec.rb +153 -82
- data/spec/error_spec.rb +15 -0
- data/spec/examples/channel_of_channels_spec.rb +17 -14
- data/spec/examples/producer_consumer_spec.rb +26 -16
- data/spec/examples/sieve_spec.rb +43 -37
- data/spec/go_spec.rb +17 -0
- data/spec/notifier_spec.rb +42 -0
- data/spec/once_spec.rb +91 -0
- data/spec/pop_spec.rb +97 -0
- data/spec/push_spec.rb +95 -0
- data/spec/queue_spec.rb +335 -37
- data/spec/queues_spec.rb +28 -0
- data/spec/selector_spec.rb +398 -0
- data/spec/spec_helper.rb +19 -0
- data/spec/uuid_spec.rb +13 -0
- data/spec/wait_group_spec.rb +45 -0
- metadata +94 -54
- data/lib/agent/transport/queue.rb +0 -82
- data/spec/helper.rb +0 -5
data/spec/pop_spec.rb
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Agent::Pop do
|
4
|
+
|
5
|
+
context "in its basic operation" do
|
6
|
+
before do
|
7
|
+
@pop = Agent::Pop.new
|
8
|
+
@ack = channel!(Time)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should close" do
|
12
|
+
@pop.should_not be_closed
|
13
|
+
@pop.close
|
14
|
+
@pop.should be_closed
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should run multiple times" do
|
18
|
+
@pop.send{Marshal.dump(1)}
|
19
|
+
@pop.should be_received
|
20
|
+
@pop.send{Marshal.dump(2)}
|
21
|
+
@pop.object.should == 2
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should continue when received" do
|
25
|
+
go!{ @pop.wait; @ack.send(Time.now) }
|
26
|
+
sleep 0.2
|
27
|
+
@pop.send{Marshal.dump(1)}
|
28
|
+
|
29
|
+
s, _ = @ack.receive
|
30
|
+
|
31
|
+
(Time.now - s).should be_within(0.01).of(0)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should continue when closed" do
|
35
|
+
go!{ @pop.wait; @ack.send(Time.now) }
|
36
|
+
sleep 0.2
|
37
|
+
@pop.close
|
38
|
+
|
39
|
+
s, _ = @ack.receive
|
40
|
+
|
41
|
+
(Time.now - s).should be_within(0.01).of(0)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "be able to be gracefully rolled back" do
|
45
|
+
@pop.should_not be_received
|
46
|
+
@pop.send{ raise Agent::Errors::Rollback }
|
47
|
+
@pop.should_not be_received
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context "with a blocking_once" do
|
52
|
+
before do
|
53
|
+
@blocking_once = Agent::BlockingOnce.new
|
54
|
+
@pop = Agent::Pop.new(:blocking_once => @blocking_once)
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should only send only once" do
|
58
|
+
@blocking_once.should_not be_performed
|
59
|
+
@pop.send{Marshal.dump(1)}
|
60
|
+
@pop.should be_received
|
61
|
+
@blocking_once.should be_performed
|
62
|
+
|
63
|
+
@pop.send{Marshal.dump(2)}
|
64
|
+
@pop.object.should == 1
|
65
|
+
|
66
|
+
lambda{@pop.send{raise "an error"} }.should_not raise_error
|
67
|
+
end
|
68
|
+
|
69
|
+
it "be able to be gracefully rolled back" do
|
70
|
+
@blocking_once.should_not be_performed
|
71
|
+
@pop.should_not be_received
|
72
|
+
@pop.send{ raise Agent::Errors::Rollback }
|
73
|
+
@blocking_once.should_not be_performed
|
74
|
+
@pop.should_not be_received
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context "with a notifier" do
|
79
|
+
before do
|
80
|
+
@notifier = Agent::Notifier.new
|
81
|
+
@pop = Agent::Pop.new(:notifier => @notifier)
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should notify when being sent" do
|
85
|
+
@notifier.should_not be_notified
|
86
|
+
@pop.send{Marshal.dump(1)}
|
87
|
+
@notifier.should be_notified
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should notify when being closed" do
|
91
|
+
@notifier.should_not be_notified
|
92
|
+
@pop.close
|
93
|
+
@notifier.should be_notified
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
data/spec/push_spec.rb
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Agent::Push do
|
4
|
+
|
5
|
+
context "in its basic operation" do
|
6
|
+
before do
|
7
|
+
@push = Agent::Push.new("1")
|
8
|
+
@ack = channel!(Time)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should close" do
|
12
|
+
@push.should_not be_closed
|
13
|
+
@push.close
|
14
|
+
@push.should be_closed
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should run multiple times" do
|
18
|
+
i = 0
|
19
|
+
@push.receive{|v| i += 1 }
|
20
|
+
@push.should be_sent
|
21
|
+
@push.receive{|v| i += 1 }
|
22
|
+
i.should == 2
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should continue when sent" do
|
26
|
+
go!{ @push.wait; @ack.send(Time.now) }
|
27
|
+
sleep 0.2
|
28
|
+
@push.receive{|v|}
|
29
|
+
|
30
|
+
s, _ = @ack.receive
|
31
|
+
|
32
|
+
(Time.now - s).should be_within(0.01).of(0)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should raise an error on the waiter when closed" do
|
36
|
+
go!{ sleep 0.1; @push.close }
|
37
|
+
lambda{ @push.wait }.should raise_error(Agent::Errors::ChannelClosed)
|
38
|
+
end
|
39
|
+
|
40
|
+
it "be able to be gracefully rolled back" do
|
41
|
+
@push.should_not be_sent
|
42
|
+
@push.receive{|v| raise Agent::Errors::Rollback }
|
43
|
+
@push.should_not be_sent
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context "with a blocking_once" do
|
48
|
+
before do
|
49
|
+
@blocking_once = Agent::BlockingOnce.new
|
50
|
+
@push = Agent::Push.new("1", :blocking_once => @blocking_once)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should only send only once" do
|
54
|
+
i = 0
|
55
|
+
|
56
|
+
@blocking_once.should_not be_performed
|
57
|
+
@push.receive{|v| i += 1 }
|
58
|
+
@push.should be_sent
|
59
|
+
@blocking_once.should be_performed
|
60
|
+
|
61
|
+
@push.receive{|v| i += 1 }
|
62
|
+
i.should == 1
|
63
|
+
|
64
|
+
lambda{@push.receive{raise "an error"} }.should_not raise_error
|
65
|
+
end
|
66
|
+
|
67
|
+
it "be able to be gracefully rolled back" do
|
68
|
+
@blocking_once.should_not be_performed
|
69
|
+
@push.should_not be_sent
|
70
|
+
@push.receive{|v| raise Agent::Errors::Rollback }
|
71
|
+
@blocking_once.should_not be_performed
|
72
|
+
@push.should_not be_sent
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context "with a notifier" do
|
77
|
+
before do
|
78
|
+
@notifier = Agent::Notifier.new
|
79
|
+
@push = Agent::Push.new("1", :notifier => @notifier)
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should notify when being sent" do
|
83
|
+
@notifier.should_not be_notified
|
84
|
+
@push.receive{|v|}
|
85
|
+
@notifier.should be_notified
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should notify when being closed" do
|
89
|
+
@notifier.should_not be_notified
|
90
|
+
@push.close
|
91
|
+
@notifier.should be_notified
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
data/spec/queue_spec.rb
CHANGED
@@ -1,53 +1,351 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
|
-
describe Agent::
|
4
|
-
include Agent::Transport
|
3
|
+
describe Agent::Queue do
|
5
4
|
|
6
|
-
|
7
|
-
|
5
|
+
context "with an buffered queue" do
|
6
|
+
before do
|
7
|
+
@queue = Agent::Queue::Buffered.new(String, 2)
|
8
|
+
end
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
10
|
+
it "should be buffered" do
|
11
|
+
@queue.should be_buffered
|
12
|
+
end
|
12
13
|
|
13
|
-
|
14
|
-
|
14
|
+
it "should not be unbuffered" do
|
15
|
+
@queue.should_not be_unbuffered
|
16
|
+
end
|
15
17
|
|
16
|
-
|
17
|
-
|
18
|
-
|
18
|
+
it "should raise an error if the queue size is <= 0" do
|
19
|
+
lambda{ Agent::Queue::Buffered.new(String, 0) }.should raise_error(Agent::Errors::InvalidQueueSize)
|
20
|
+
lambda{ Agent::Queue::Buffered.new(String, -1) }.should raise_error(Agent::Errors::InvalidQueueSize)
|
21
|
+
end
|
19
22
|
|
20
|
-
|
21
|
-
|
23
|
+
it "should raise an erro when an object of an invalid type is pushed" do
|
24
|
+
lambda { @queue.push(1) }.should raise_error(Agent::Errors::InvalidType)
|
25
|
+
end
|
22
26
|
|
23
|
-
|
24
|
-
|
25
|
-
q.async?.should be_true
|
27
|
+
it "should enqueue and dequeue in order" do
|
28
|
+
20.times{|i| @queue.push(i.to_s, :deferred => true) }
|
26
29
|
|
27
|
-
|
28
|
-
lambda { q.send("hello 2", true) }.should_not raise_error(ThreadError, "buffer full")
|
29
|
-
lambda { q.send("hello 3", true) }.should raise_error(ThreadError, "buffer full")
|
30
|
+
previous = -1
|
30
31
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
32
|
+
20.times do |i|
|
33
|
+
o = @queue.pop[0].to_i
|
34
|
+
o.should > previous
|
35
|
+
previous = o
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context "when the queue is empty" do
|
40
|
+
it "should hold any attempts to pop from it" do
|
41
|
+
@queue.operations.should be_empty
|
42
|
+
@queue.pop(:deferred => true)
|
43
|
+
@queue.operations.should_not be_empty
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should be able to be pushed to" do
|
47
|
+
@queue.push("1")
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should increase in size when pushed to" do
|
51
|
+
@queue.size.should == 0
|
52
|
+
@queue.push("1")
|
53
|
+
@queue.size.should == 1
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should be pushable" do
|
57
|
+
@queue.push?.should == true
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should not be poppable" do
|
61
|
+
@queue.pop?.should == false
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context "when there are elements in the queue and still space left" do
|
66
|
+
before do
|
67
|
+
@queue.push("1")
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should be able to be pushed to" do
|
71
|
+
@queue.push("1")
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should increase in size when pushed to" do
|
75
|
+
@queue.size.should == 1
|
76
|
+
@queue.push("1")
|
77
|
+
@queue.size.should == 2
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should be able to be popped from" do
|
81
|
+
@queue.pop[0].should == "1"
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should decrease in size when popped from" do
|
85
|
+
@queue.size.should == 1
|
86
|
+
@queue.pop
|
87
|
+
@queue.size.should == 0
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should be pushable" do
|
91
|
+
@queue.push?.should == true
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should be poppable" do
|
95
|
+
@queue.pop?.should == true
|
96
|
+
end
|
97
|
+
end
|
35
98
|
|
36
|
-
|
37
|
-
|
38
|
-
|
99
|
+
context "when the queue is full" do
|
100
|
+
before do
|
101
|
+
2.times { @queue.push("1") }
|
102
|
+
end
|
39
103
|
|
40
|
-
|
41
|
-
|
104
|
+
it "should hold any attempts to push to it" do
|
105
|
+
@queue.operations.should be_empty
|
106
|
+
@queue.push("1", :deferred => true)
|
107
|
+
@queue.operations.should_not be_empty
|
108
|
+
end
|
109
|
+
|
110
|
+
it "should be able to be popped from" do
|
111
|
+
@queue.pop[0].should == "1"
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should not be pushable" do
|
115
|
+
@queue.push?.should == false
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should be poppable" do
|
119
|
+
@queue.pop?.should == true
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
context "when being closed" do
|
124
|
+
before do
|
125
|
+
@push1, @push2, @push3 = (1..3).map{ @queue.push("1", :deferred => true) }
|
126
|
+
end
|
127
|
+
|
128
|
+
it "should go from open to closed" do
|
129
|
+
@queue.should_not be_closed
|
130
|
+
@queue.should be_open
|
131
|
+
@queue.close
|
132
|
+
@queue.should be_closed
|
133
|
+
@queue.should_not be_open
|
134
|
+
end
|
135
|
+
|
136
|
+
it "should close all the waiting operations" do
|
137
|
+
@push1.should be_sent
|
138
|
+
@push2.should be_sent
|
139
|
+
@push3.should_not be_sent
|
140
|
+
@push3.should_not be_closed
|
141
|
+
|
142
|
+
@queue.close
|
143
|
+
|
144
|
+
@push3.should be_closed
|
145
|
+
end
|
146
|
+
|
147
|
+
it "should clear all waiting operations" do
|
148
|
+
@queue.operations.size.should == 1
|
149
|
+
@queue.pushes.size.should == 1
|
150
|
+
@queue.close
|
151
|
+
@queue.operations.size.should == 0
|
152
|
+
@queue.pushes.size.should == 0
|
153
|
+
end
|
154
|
+
|
155
|
+
it "should clear all elements at rest" do
|
156
|
+
@queue.queue.size.should == 2
|
157
|
+
@queue.close
|
158
|
+
@queue.queue.size.should == 0
|
159
|
+
end
|
160
|
+
|
161
|
+
it "should raise an error when being acted upon afterwards" do
|
162
|
+
@queue.close
|
163
|
+
lambda{ @queue.close }.should raise_error(Agent::Errors::ChannelClosed)
|
164
|
+
lambda{ @queue.push("1") }.should raise_error(Agent::Errors::ChannelClosed)
|
165
|
+
lambda{ @queue.pop }.should raise_error(Agent::Errors::ChannelClosed)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
context "when removing operations" do
|
170
|
+
before do
|
171
|
+
@pushes = (1..8).map{|i| @queue.push(i.to_s, :deferred => true) }
|
172
|
+
end
|
173
|
+
|
174
|
+
it "should remove the operations" do
|
175
|
+
removable_pushes = @pushes.values_at(5, 6) # values "6" and "7"
|
176
|
+
@queue.remove_operations(removable_pushes)
|
177
|
+
while @queue.pop?
|
178
|
+
i = @queue.pop[0]
|
179
|
+
i.should_not be_nil
|
180
|
+
i.should_not == "6"
|
181
|
+
i.should_not == "7"
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
42
185
|
end
|
43
186
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
187
|
+
context "with a unbuffered queue" do
|
188
|
+
before do
|
189
|
+
@queue = Agent::Queue::Unbuffered.new(String)
|
190
|
+
end
|
191
|
+
|
192
|
+
it "should not be buffered" do
|
193
|
+
@queue.should_not be_buffered
|
194
|
+
end
|
48
195
|
|
49
|
-
|
50
|
-
|
51
|
-
|
196
|
+
it "should be unbuffered" do
|
197
|
+
@queue.should be_unbuffered
|
198
|
+
end
|
199
|
+
|
200
|
+
it "should enqueue and dequeue in order" do
|
201
|
+
20.times{|i| @queue.push(i.to_s, :deferred => true) }
|
202
|
+
|
203
|
+
previous = -1
|
204
|
+
|
205
|
+
20.times do |i|
|
206
|
+
o = @queue.pop[0].to_i
|
207
|
+
o.should > previous
|
208
|
+
previous = o
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
context "when there are no operations waiting" do
|
213
|
+
it "should not be poppable" do
|
214
|
+
@queue.pop?.should == false
|
215
|
+
end
|
216
|
+
|
217
|
+
it "should not be pushable" do
|
218
|
+
@queue.push?.should == false
|
219
|
+
end
|
220
|
+
|
221
|
+
it "should queue pushes" do
|
222
|
+
@queue.operations.size.should == 0
|
223
|
+
push = @queue.push("1", :deferred => true)
|
224
|
+
push.should_not be_sent
|
225
|
+
@queue.operations.size.should == 1
|
226
|
+
end
|
227
|
+
|
228
|
+
it "should queue pops" do
|
229
|
+
@queue.operations.size.should == 0
|
230
|
+
pop = @queue.pop(:deferred => true)
|
231
|
+
pop.should_not be_received
|
232
|
+
@queue.operations.size.should == 1
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
context "when there is a pop waiting" do
|
237
|
+
before do
|
238
|
+
@pop = @queue.pop(:deferred => true)
|
239
|
+
end
|
240
|
+
|
241
|
+
it "should not be poppable" do
|
242
|
+
@queue.pop?.should == false
|
243
|
+
end
|
244
|
+
|
245
|
+
it "should be pushable" do
|
246
|
+
@queue.push?.should == true
|
247
|
+
end
|
248
|
+
|
249
|
+
it "should execute a push and the waiting pop immediately" do
|
250
|
+
push = @queue.push("1", :deferred => true)
|
251
|
+
@pop.should be_received
|
252
|
+
push.should be_sent
|
253
|
+
@pop.object.should == "1"
|
254
|
+
end
|
255
|
+
|
256
|
+
it "should queue pops" do
|
257
|
+
@queue.operations.size.should == 1
|
258
|
+
pop = @queue.pop(:deferred => true)
|
259
|
+
pop.should_not be_received
|
260
|
+
@queue.operations.size.should == 2
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
context "when there is a push waiting" do
|
265
|
+
before do
|
266
|
+
@push = @queue.push("1", :deferred => true)
|
267
|
+
end
|
268
|
+
|
269
|
+
it "should be poppable" do
|
270
|
+
@queue.pop?.should == true
|
271
|
+
end
|
272
|
+
|
273
|
+
it "should not be pushable" do
|
274
|
+
@queue.push?.should == false
|
275
|
+
end
|
276
|
+
|
277
|
+
it "should queue pushes" do
|
278
|
+
@queue.operations.size.should == 1
|
279
|
+
push = @queue.push("1", :deferred => true)
|
280
|
+
push.should_not be_sent
|
281
|
+
@queue.operations.size.should == 2
|
282
|
+
end
|
283
|
+
|
284
|
+
it "should execute a pop and the waiting push immediately" do
|
285
|
+
pop = @queue.pop(:deferred => true)
|
286
|
+
@push.should be_sent
|
287
|
+
pop.should be_received
|
288
|
+
pop.object.should == "1"
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
context "when being closed" do
|
293
|
+
before do
|
294
|
+
@push1, @push2 = (1..2).map{ @queue.push("1", :deferred => true) }
|
295
|
+
end
|
296
|
+
|
297
|
+
it "should go from open to closed" do
|
298
|
+
@queue.should_not be_closed
|
299
|
+
@queue.should be_open
|
300
|
+
@queue.close
|
301
|
+
@queue.should be_closed
|
302
|
+
@queue.should_not be_open
|
303
|
+
end
|
304
|
+
|
305
|
+
it "should close all the waiting operations" do
|
306
|
+
@push1.should_not be_sent
|
307
|
+
@push1.should_not be_closed
|
308
|
+
@push2.should_not be_sent
|
309
|
+
@push2.should_not be_closed
|
310
|
+
|
311
|
+
@queue.close
|
312
|
+
|
313
|
+
@push1.should be_closed
|
314
|
+
@push2.should be_closed
|
315
|
+
end
|
316
|
+
|
317
|
+
it "should clear all waiting operations" do
|
318
|
+
@queue.operations.size.should == 2
|
319
|
+
@queue.pushes.size.should == 2
|
320
|
+
@queue.close
|
321
|
+
@queue.operations.size.should == 0
|
322
|
+
@queue.pushes.size.should == 0
|
323
|
+
end
|
324
|
+
|
325
|
+
it "should raise an error when being acted upon afterwards" do
|
326
|
+
@queue.close
|
327
|
+
lambda{ @queue.close }.should raise_error(Agent::Errors::ChannelClosed)
|
328
|
+
lambda{ @queue.push("1") }.should raise_error(Agent::Errors::ChannelClosed)
|
329
|
+
lambda{ @queue.pop }.should raise_error(Agent::Errors::ChannelClosed)
|
330
|
+
end
|
331
|
+
end
|
332
|
+
|
333
|
+
context "when removing operations" do
|
334
|
+
before do
|
335
|
+
@pushes = (1..8).map{|i| @queue.push(i.to_s, :deferred => true) }
|
336
|
+
end
|
337
|
+
|
338
|
+
it "should remove the operations" do
|
339
|
+
removable_pushes = @pushes.values_at(5, 6) # values "6" and "7"
|
340
|
+
@queue.remove_operations(removable_pushes)
|
341
|
+
while @queue.pop?
|
342
|
+
i = @queue.pop[0]
|
343
|
+
i.should_not be_nil
|
344
|
+
i.should_not == "6"
|
345
|
+
i.should_not == "7"
|
346
|
+
end
|
347
|
+
end
|
348
|
+
end
|
349
|
+
end
|
52
350
|
|
53
351
|
end
|