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.
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: