refilling_queue 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- refilling_queue (0.0.1)
4
+ refilling_queue (0.0.2)
5
5
 
6
6
  GEM
7
7
  remote: http://rubygems.org/
data/Readme.md CHANGED
@@ -14,8 +14,8 @@ Usage
14
14
 
15
15
  begin
16
16
  queue.pop
17
- rescue
18
- RefillingQueue::EmptyRefill # queue was empty, refilled but is still empty
17
+ rescue RefillingQueue::Locked
18
+ # queue was empty, refilling failed because other process is already trying it
19
19
  end
20
20
 
21
21
  queue.pop -> return id
@@ -23,6 +23,8 @@ Usage
23
23
  queue.pop -> run block -> store new ids -> return id
24
24
  ... # 30 seconds elapsed (global expires_at stored in reque_client) ?
25
25
  queue.pop -> run block -> store new ids -> return id
26
+ ...
27
+ queue.pop -> run block -> empty result -> return nil
26
28
 
27
29
  Author
28
30
  ======
@@ -1,7 +1,7 @@
1
1
  require 'refilling_queue/version'
2
2
 
3
3
  class RefillingQueue
4
- class EmptyRefill < RuntimeError
4
+ class Locked < RuntimeError
5
5
  end
6
6
 
7
7
  DEFAULT_OPTIONS = {
@@ -16,20 +16,23 @@ class RefillingQueue
16
16
  end
17
17
 
18
18
  def pop
19
- item = @client.lpop @name
19
+ item = _pop
20
20
  return item unless item.nil?
21
-
22
21
  refill
22
+ _pop
23
+ end
23
24
 
24
- item = @client.lpop @name
25
- return item unless item.nil?
25
+ private
26
26
 
27
- raise RefillingQueue::EmptyRefill
27
+ def _pop
28
+ @client.lpop @name
28
29
  end
29
30
 
30
31
  def refill
31
32
  lock do
32
33
  results = @block.call
34
+ return if results.empty?
35
+
33
36
  @client.pipelined do
34
37
  @client.del @name
35
38
  results.each{ |r| @client.rpush @name, r } # TODO https://github.com/redis/redis-rb/issues/253
@@ -42,11 +45,9 @@ class RefillingQueue
42
45
  @client.llen(@name) == 0
43
46
  end
44
47
 
45
- private
46
-
47
48
  def lock
48
49
  lock = "#{@name}_lock"
49
- return unless @client.setnx lock, "1"
50
+ raise RefillingQueue::Locked unless @client.setnx lock, "1"
50
51
  @client.expire lock, @options[:lock_timeout]
51
52
  begin
52
53
  yield
@@ -1,3 +1,3 @@
1
1
  class RefillingQueue
2
- VERSION = '0.0.1'
2
+ VERSION = '0.0.2'
3
3
  end
@@ -32,12 +32,9 @@ describe RefillingQueue do
32
32
  queue.pop.should == 3
33
33
  end
34
34
 
35
- it "only tries to refill once / raises on empty refill" do
35
+ it "only tries to refill once" do
36
36
  calls = []
37
- queue = RefillingQueue.new(client, "x"){ calls << 1; [] }
38
- expect{
39
- queue.pop
40
- }.to raise_error(RefillingQueue::EmptyRefill)
37
+ RefillingQueue.new(client, "x"){ calls << 1; [] }.pop.should == nil
41
38
  calls.should == [1]
42
39
  end
43
40
 
@@ -67,14 +64,27 @@ describe RefillingQueue do
67
64
  context "with multiple actors" do
68
65
  it "only refills once" do
69
66
  called = []
67
+
68
+ # lock-blocker
70
69
  Thread.new do
71
70
  RefillingQueue.new(client, "x"){ sleep 0.2; called << 1; [] }.pop
72
71
  end
72
+ sleep 0.1
73
+
74
+ # blocked
75
+ locked = false
73
76
  Thread.new do
74
- RefillingQueue.new(client, "x"){ sleep 0.2; called << 1; [] }.pop
77
+ queue = RefillingQueue.new(client, "x"){ sleep 0.2; called << 1; [] }
78
+ begin
79
+ queue.pop
80
+ rescue RefillingQueue::Locked
81
+ locked = true
82
+ end
75
83
  end
76
84
  sleep 0.3
85
+
77
86
  called.should == [1]
87
+ locked.should == true
78
88
  end
79
89
 
80
90
  it "can refill after refill is complete" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: refilling_queue
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-07-12 00:00:00.000000000 Z
12
+ date: 2012-07-13 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description:
15
15
  email: michael@grosser.it
@@ -42,7 +42,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
42
42
  version: '0'
43
43
  segments:
44
44
  - 0
45
- hash: -2693512841144003384
45
+ hash: 2863148755919563971
46
46
  required_rubygems_version: !ruby/object:Gem::Requirement
47
47
  none: false
48
48
  requirements:
@@ -51,7 +51,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
51
51
  version: '0'
52
52
  segments:
53
53
  - 0
54
- hash: -2693512841144003384
54
+ hash: 2863148755919563971
55
55
  requirements: []
56
56
  rubyforge_project:
57
57
  rubygems_version: 1.8.24