refilling_queue 0.0.1 → 0.0.2
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/Gemfile.lock +1 -1
- data/Readme.md +4 -2
- data/lib/refilling_queue.rb +10 -9
- data/lib/refilling_queue/version.rb +1 -1
- data/spec/refilling_queue_spec.rb +16 -6
- metadata +4 -4
data/Gemfile.lock
CHANGED
data/Readme.md
CHANGED
@@ -14,8 +14,8 @@ Usage
|
|
14
14
|
|
15
15
|
begin
|
16
16
|
queue.pop
|
17
|
-
rescue
|
18
|
-
|
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
|
======
|
data/lib/refilling_queue.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'refilling_queue/version'
|
2
2
|
|
3
3
|
class RefillingQueue
|
4
|
-
class
|
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 =
|
19
|
+
item = _pop
|
20
20
|
return item unless item.nil?
|
21
|
-
|
22
21
|
refill
|
22
|
+
_pop
|
23
|
+
end
|
23
24
|
|
24
|
-
|
25
|
-
return item unless item.nil?
|
25
|
+
private
|
26
26
|
|
27
|
-
|
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
|
-
|
50
|
+
raise RefillingQueue::Locked unless @client.setnx lock, "1"
|
50
51
|
@client.expire lock, @options[:lock_timeout]
|
51
52
|
begin
|
52
53
|
yield
|
@@ -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
|
35
|
+
it "only tries to refill once" do
|
36
36
|
calls = []
|
37
|
-
|
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; [] }
|
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.
|
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
|
+
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:
|
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:
|
54
|
+
hash: 2863148755919563971
|
55
55
|
requirements: []
|
56
56
|
rubyforge_project:
|
57
57
|
rubygems_version: 1.8.24
|