super_queue 0.0.8 → 0.0.9
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/lib/super_queue.rb +64 -57
- metadata +1 -1
data/lib/super_queue.rb
CHANGED
@@ -17,8 +17,7 @@ class SuperQueue
|
|
17
17
|
def initialize(opts)
|
18
18
|
check_opts(opts)
|
19
19
|
opts[:localize_queue] = true unless opts.has_key? :localized_queue
|
20
|
-
opts[:buffer_size]
|
21
|
-
|
20
|
+
@buffer_size = opts[:buffer_size] || 100
|
22
21
|
@localize_queue = opts[:localize_queue]
|
23
22
|
@queue_name = generate_queue_name(opts)
|
24
23
|
initialize_sqs(opts)
|
@@ -27,19 +26,19 @@ class SuperQueue
|
|
27
26
|
@waiting.taint
|
28
27
|
self.taint
|
29
28
|
@mutex = Mutex.new
|
30
|
-
@in_buffer =
|
31
|
-
@out_buffer =
|
32
|
-
@deletion_queue =
|
29
|
+
@in_buffer = []
|
30
|
+
@out_buffer = []
|
31
|
+
@deletion_queue = []
|
33
32
|
@mock_length = 0 if SuperQueue.mocking?
|
34
33
|
|
35
|
-
@
|
36
|
-
@
|
37
|
-
@garbage_collector = Thread.new { collect_garbage }
|
34
|
+
@sqs_tracker = Thread.new { poll_sqs }
|
35
|
+
@gc = Thread.new { collect_garbage }
|
38
36
|
end
|
39
37
|
|
40
38
|
def push(p)
|
41
39
|
@mutex.synchronize {
|
42
40
|
@in_buffer.push p
|
41
|
+
clear_in_buffer if @in_buffer.size >= @buffer_size
|
43
42
|
begin
|
44
43
|
t = @waiting.shift
|
45
44
|
t.wakeup if t
|
@@ -54,14 +53,14 @@ class SuperQueue
|
|
54
53
|
while true
|
55
54
|
if @out_buffer.empty?
|
56
55
|
if fill_out_buffer_from_sqs_queue || fill_out_buffer_from_in_buffer
|
57
|
-
return pop_out_buffer
|
56
|
+
return pop_out_buffer
|
58
57
|
else
|
59
58
|
raise ThreadError, "queue empty" if non_block
|
60
59
|
@waiting.push Thread.current
|
61
60
|
@mutex.sleep
|
62
61
|
end
|
63
62
|
else
|
64
|
-
return pop_out_buffer
|
63
|
+
return pop_out_buffer
|
65
64
|
end
|
66
65
|
end
|
67
66
|
}
|
@@ -90,21 +89,15 @@ class SuperQueue
|
|
90
89
|
end
|
91
90
|
|
92
91
|
def shutdown
|
93
|
-
@
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
@sqs_tail_tracker.terminate
|
98
|
-
@garbage_collector.terminate
|
99
|
-
while !@deletion_queue.empty?
|
100
|
-
@sqs.delete_message(q_url, @deletion_queue.pop)
|
101
|
-
end
|
92
|
+
@sqs_tracker.terminate
|
93
|
+
@mutex.synchronize { clear_in_buffer }
|
94
|
+
@gc.terminate
|
95
|
+
@mutex.synchronize { clear_deletion_queue }
|
102
96
|
end
|
103
97
|
|
104
98
|
def destroy
|
105
|
-
@
|
106
|
-
@
|
107
|
-
@garbage_collector.terminate
|
99
|
+
@sqs_tracker.terminate
|
100
|
+
@gc.terminate
|
108
101
|
delete_queue
|
109
102
|
end
|
110
103
|
|
@@ -130,6 +123,22 @@ class SuperQueue
|
|
130
123
|
|
131
124
|
private
|
132
125
|
|
126
|
+
def poll_sqs
|
127
|
+
loop do
|
128
|
+
@mutex.synchronize { fill_out_buffer_from_sqs_queue || fill_out_buffer_from_in_buffer } if @out_buffer.empty?
|
129
|
+
@mutex.synchronize { clear_in_buffer } if !@in_buffer.empty? && (@in_buffer.size > @buffer_size)
|
130
|
+
Thread.pass
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def collect_garbage
|
135
|
+
loop do
|
136
|
+
#This also needs a condition to clear the del queue if there are any handles where the invisibility is about to expire
|
137
|
+
@mutex.synchronize { clear_deletion_queue } if !@deletion_queue.empty? && (@deletion_queue.size >= (@buffer_size / 2))
|
138
|
+
sleep
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
133
142
|
def check_opts(opts)
|
134
143
|
raise "Options can't be nil!" if opts.nil?
|
135
144
|
raise "Minimun :buffer_size is 5." if opts[:buffer_size] && (opts[:buffer_size] < 5)
|
@@ -179,7 +188,8 @@ class SuperQueue
|
|
179
188
|
raise "Couldn't create queue #{queue_name}, or delete existing queue by this name." if q_url.nil?
|
180
189
|
end
|
181
190
|
|
182
|
-
def send_message_to_queue
|
191
|
+
def send_message_to_queue
|
192
|
+
p = @in_buffer.shift
|
183
193
|
payload = is_a_link?(p) ? p : Base64.encode64(Marshal.dump(p))
|
184
194
|
@sqs.send_message(q_url, payload)
|
185
195
|
@mock_length += 1 if SuperQueue.mocking?
|
@@ -248,55 +258,39 @@ class SuperQueue
|
|
248
258
|
orig, Socket.do_not_reverse_lookup = Socket.do_not_reverse_lookup, true # turn off reverse DNS resolution temporarily
|
249
259
|
return "127.0.0.1" if SuperQueue.mocking?
|
250
260
|
UDPSocket.open do |s|
|
251
|
-
s.connect '64.233.187.99', 1
|
261
|
+
s.connect '64.233.187 .99', 1
|
252
262
|
s.addr.last
|
253
263
|
end
|
254
264
|
ensure
|
255
265
|
Socket.do_not_reverse_lookup = orig
|
256
266
|
end
|
257
267
|
|
258
|
-
def poll_sqs_head
|
259
|
-
loop { send_message_to_queue(@in_buffer.pop) }
|
260
|
-
end
|
261
|
-
|
262
|
-
def poll_sqs_tail
|
263
|
-
loop do
|
264
|
-
nil_count = 0
|
265
|
-
while (@out_buffer.size < @out_buffer.max) && (nil_count < 5) # If you get nil 5 times in a row, SQS is probably empty
|
266
|
-
m = get_message_from_queue
|
267
|
-
if m.nil?
|
268
|
-
nil_count += 1
|
269
|
-
else
|
270
|
-
@out_buffer.push m
|
271
|
-
nil_count = 0
|
272
|
-
end
|
273
|
-
end unless sqs_length == 0
|
274
|
-
sleep
|
275
|
-
end
|
276
|
-
end
|
277
|
-
|
278
|
-
def collect_garbage
|
279
|
-
loop { @sqs.delete_message(q_url, @deletion_queue.pop) }
|
280
|
-
end
|
281
|
-
|
282
268
|
def fill_out_buffer_from_sqs_queue
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
269
|
+
return false if sqs_length == 0
|
270
|
+
@gc.wakeup if @gc.stop? # This is the best time to do GC, because there are no pops happening.
|
271
|
+
nil_count = 0
|
272
|
+
while (@out_buffer.size < @buffer_size) && (nil_count < 5) # If you get nil 5 times in a row, SQS is probably empty
|
273
|
+
m = get_message_from_queue
|
274
|
+
if m.nil?
|
275
|
+
nil_count += 1
|
276
|
+
else
|
277
|
+
@out_buffer.push m
|
278
|
+
nil_count = 0
|
279
|
+
end
|
288
280
|
end
|
281
|
+
!@out_buffer.empty?
|
289
282
|
end
|
290
283
|
|
291
284
|
def fill_out_buffer_from_in_buffer
|
292
|
-
|
293
|
-
|
285
|
+
return false if @in_buffer.empty?
|
286
|
+
while (@out_buffer.size <= @buffer_size) && !@in_buffer.empty?
|
287
|
+
@out_buffer.push(:payload => @in_buffer.shift)
|
294
288
|
end
|
295
289
|
!@out_buffer.empty?
|
296
290
|
end
|
297
291
|
|
298
|
-
def pop_out_buffer
|
299
|
-
m = @out_buffer.
|
292
|
+
def pop_out_buffer
|
293
|
+
m = @out_buffer.shift
|
300
294
|
@deletion_queue << m[:handle] if m[:handle]
|
301
295
|
m[:payload]
|
302
296
|
end
|
@@ -304,4 +298,17 @@ class SuperQueue
|
|
304
298
|
def queue_name
|
305
299
|
@queue_name
|
306
300
|
end
|
301
|
+
|
302
|
+
def clear_in_buffer
|
303
|
+
while !@in_buffer.empty? do
|
304
|
+
send_message_to_queue
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
def clear_deletion_queue
|
309
|
+
while !@deletion_queue.empty?
|
310
|
+
@sqs.delete_message(q_url, @deletion_queue.shift)
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
307
314
|
end
|