super_queue 0.0.8 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (2) hide show
  1. data/lib/super_queue.rb +64 -57
  2. 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] = 100 unless opts.has_key? :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 = SizedQueue.new(opts[:buffer_size])
31
- @out_buffer = SizedQueue.new(opts[:buffer_size])
32
- @deletion_queue = Queue.new
29
+ @in_buffer = []
30
+ @out_buffer = []
31
+ @deletion_queue = []
33
32
  @mock_length = 0 if SuperQueue.mocking?
34
33
 
35
- @sqs_head_tracker = Thread.new { poll_sqs_head }
36
- @sqs_tail_tracker = Thread.new { poll_sqs_tail }
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(non_block)
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(non_block)
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
- @sqs_head_tracker.terminate
94
- while !@in_buffer.empty? do
95
- @sqs.delete_message(q_url, @in_buffer.pop)
96
- end
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
- @sqs_head_tracker.terminate
106
- @sqs_tail_tracker.terminate
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(p)
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
- @sqs_tail_tracker.wakeup if @sqs_tail_tracker.stop?
284
- count = 0
285
- while @out_buffer.empty? && count != 5
286
- sleep 1
287
- count += 1
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
- while (@out_buffer.size < @out_buffer.max) && !@in_buffer.empty?
293
- @out_buffer.push(:payload => @in_buffer.pop)
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(non_block)
299
- m = @out_buffer.pop(non_block)
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
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: super_queue
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.8
4
+ version: 0.0.9
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors: