coordinator 0.0.2 → 0.0.3
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.
- checksums.yaml +4 -4
- data/lib/coordinator/base.rb +17 -6
- data/lib/coordinator/queue.rb +20 -1
- data/lib/coordinator/redis_queue.rb +8 -9
- data/lib/coordinator/version.rb +1 -1
- data/test/unit/base_test.rb +9 -0
- data/test/unit/parallelism_test.rb +45 -0
- data/test/unit/queue_test.rb +16 -0
- data/test/unit/redis_queue_test.rb +10 -6
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d30f4f717a647bb842456b00f951a25f613492ab
|
4
|
+
data.tar.gz: 96401cd4398ef8040044a89a711bbb77d3831f80
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 351d5200dc09beff1d9f3060fbb89fbbeec754aa83289ccc9ed23951e3e50571e78215989b79ae713dbc4ac189a15dba9d0eff333e208be311b8a9f8a7e72fa5
|
7
|
+
data.tar.gz: 4c1d21850138d1ca67c5f820dc977243ce8f4f28473a8efa8b57da88c04306285da85e26ae59ece072993f9eafb0ac27202d2e9a36cea2051fcb7b30060196c0
|
data/lib/coordinator/base.rb
CHANGED
@@ -5,13 +5,15 @@ module Coordinator
|
|
5
5
|
end
|
6
6
|
|
7
7
|
def add_task(skill, task)
|
8
|
-
|
9
|
-
queue.add_task(task)
|
8
|
+
queue_for_skill(skill).add_task(task)
|
10
9
|
end
|
11
10
|
|
12
11
|
def add_priority_task(skill, task)
|
13
|
-
|
14
|
-
|
12
|
+
queue_for_skill(skill).add_priority_task(task)
|
13
|
+
end
|
14
|
+
|
15
|
+
def remove_task(skill, task)
|
16
|
+
queue_for_skill(skill).remove_task(task)
|
15
17
|
end
|
16
18
|
|
17
19
|
def next_task(skills)
|
@@ -23,15 +25,24 @@ module Coordinator
|
|
23
25
|
end
|
24
26
|
|
25
27
|
def set_capacity(skill, capacity)
|
28
|
+
queue_for_skill(skill).set_capacity(capacity)
|
29
|
+
end
|
30
|
+
|
31
|
+
def info(skill)
|
26
32
|
queue = queue_for_skill(skill)
|
27
|
-
|
33
|
+
{
|
34
|
+
:skill => queue.skill,
|
35
|
+
:capacity => queue.capacity,
|
36
|
+
:count => queue.length,
|
37
|
+
:items => queue.items
|
38
|
+
}
|
28
39
|
end
|
29
40
|
|
30
41
|
private
|
31
42
|
|
32
43
|
def queue_for_skill(skill)
|
33
44
|
queue = @queues.find {|q| q.skill == skill}
|
34
|
-
raise Coordinator::Error
|
45
|
+
raise Coordinator::Error, "No matching queue for #{skill}" unless queue
|
35
46
|
queue
|
36
47
|
end
|
37
48
|
end
|
data/lib/coordinator/queue.rb
CHANGED
@@ -17,8 +17,15 @@ module Coordinator
|
|
17
17
|
@store.left_push(task)
|
18
18
|
end
|
19
19
|
|
20
|
+
def remove_task(task)
|
21
|
+
@store.remove(task)
|
22
|
+
end
|
23
|
+
|
20
24
|
def next_task(skills)
|
21
|
-
|
25
|
+
task = @store.peek
|
26
|
+
return nil unless task && eligible?(task, skills)
|
27
|
+
return task if @store.remove(task)
|
28
|
+
next_task(skills)
|
22
29
|
end
|
23
30
|
|
24
31
|
def eligible?(task, skills)
|
@@ -29,5 +36,17 @@ module Coordinator
|
|
29
36
|
def set_capacity(capacity)
|
30
37
|
@store.capacity = capacity
|
31
38
|
end
|
39
|
+
|
40
|
+
def items
|
41
|
+
@store.items
|
42
|
+
end
|
43
|
+
|
44
|
+
def capacity
|
45
|
+
@store.capacity
|
46
|
+
end
|
47
|
+
|
48
|
+
def length
|
49
|
+
@store.length
|
50
|
+
end
|
32
51
|
end
|
33
52
|
end
|
@@ -5,12 +5,12 @@ module Coordinator
|
|
5
5
|
def initialize(name)
|
6
6
|
@queue_name = "#{name}-queue"
|
7
7
|
@capacity_name = "#{name}-capacity"
|
8
|
-
raise Coordinator::Error
|
8
|
+
raise Coordinator::Error, "'Redis.current' not set" unless Redis.current
|
9
9
|
@redis = Redis.current
|
10
10
|
end
|
11
11
|
|
12
12
|
def push(item)
|
13
|
-
raise Coordinator::Error
|
13
|
+
raise Coordinator::Error, "Queue is at capacity" if full?
|
14
14
|
data = serialize(item)
|
15
15
|
@redis.rpush(@queue_name, data) unless items.include?(data)
|
16
16
|
end
|
@@ -27,7 +27,7 @@ module Coordinator
|
|
27
27
|
|
28
28
|
def remove(item)
|
29
29
|
data = serialize(item)
|
30
|
-
@redis.lrem(@queue_name, 1, data)
|
30
|
+
@redis.lrem(@queue_name, 1, data) == 1
|
31
31
|
end
|
32
32
|
|
33
33
|
def peek
|
@@ -48,15 +48,14 @@ module Coordinator
|
|
48
48
|
@redis.set(@capacity_name, capacity)
|
49
49
|
end
|
50
50
|
|
51
|
+
def items
|
52
|
+
@redis.lrange(@queue_name, 0, length)
|
53
|
+
end
|
54
|
+
|
51
55
|
private
|
52
56
|
|
53
57
|
def full?
|
54
|
-
|
55
|
-
length >= capacity
|
56
|
-
end
|
57
|
-
|
58
|
-
def items
|
59
|
-
@redis.lrange(@queue_name, 0, length)
|
58
|
+
capacity && capacity <= length
|
60
59
|
end
|
61
60
|
|
62
61
|
def serialize(item)
|
data/lib/coordinator/version.rb
CHANGED
data/test/unit/base_test.rb
CHANGED
@@ -27,4 +27,13 @@ describe 'Coordinator::Base' do
|
|
27
27
|
err.message.must_match /No matching queue for forgotten/
|
28
28
|
end
|
29
29
|
end
|
30
|
+
|
31
|
+
describe 'removing work' do
|
32
|
+
it 'remove task from appropriate queue' do
|
33
|
+
@coordinator.add_task("medium", 2)
|
34
|
+
@coordinator.add_priority_task("medium", 3)
|
35
|
+
@coordinator.remove_task("medium", 3)
|
36
|
+
assert_equal 2, @coordinator.next_task(["medium"])
|
37
|
+
end
|
38
|
+
end
|
30
39
|
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'time'
|
3
|
+
|
4
|
+
describe 'ParallelismTest' do
|
5
|
+
before do
|
6
|
+
@coordinator = Coordinator::Base.new([
|
7
|
+
Coordinator::Queue.new("tasks"),
|
8
|
+
Coordinator::Queue.new("completed_tasks")
|
9
|
+
])
|
10
|
+
@tasks = ('a'..'z').to_a
|
11
|
+
@tasks.each { |t| @coordinator.add_task("tasks", t) }
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'works syncronously' do
|
15
|
+
125.times { perform_work }
|
16
|
+
assert_equal [], @coordinator.info("tasks")[:items]
|
17
|
+
array_equal(@tasks, @coordinator.info("completed_tasks")[:items])
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'works in parallel' do
|
21
|
+
workers = []
|
22
|
+
|
23
|
+
start = Time.now + 1
|
24
|
+
|
25
|
+
200.times do |i|
|
26
|
+
workers << Thread.new(i) do
|
27
|
+
sleep(start - Time.now)
|
28
|
+
perform_work(i)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
workers.each { |w| w.join }
|
32
|
+
|
33
|
+
assert_equal [], @coordinator.info("tasks")[:items]
|
34
|
+
array_equal(@tasks, @coordinator.info("completed_tasks")[:items])
|
35
|
+
end
|
36
|
+
|
37
|
+
def perform_work(i=nil)
|
38
|
+
task = @coordinator.next_task(["tasks"])
|
39
|
+
@coordinator.add_task("completed_tasks", task) if task
|
40
|
+
end
|
41
|
+
|
42
|
+
def array_equal(left, right)
|
43
|
+
assert_equal left.uniq.sort, right.uniq.sort
|
44
|
+
end
|
45
|
+
end
|
data/test/unit/queue_test.rb
CHANGED
@@ -6,6 +6,22 @@ describe "Coordinator::Queue" do
|
|
6
6
|
Redis.current.flushall
|
7
7
|
end
|
8
8
|
|
9
|
+
describe "next_task" do
|
10
|
+
it "gets task for skills" do
|
11
|
+
@queue.add_task(5)
|
12
|
+
assert_equal 5, @queue.next_task(["high"])
|
13
|
+
end
|
14
|
+
|
15
|
+
it "returns nil when no eligable work" do
|
16
|
+
@queue.add_task(5)
|
17
|
+
assert_equal nil, @queue.next_task(["medium"])
|
18
|
+
end
|
19
|
+
|
20
|
+
it "returns nil when no work" do
|
21
|
+
assert_equal nil, @queue.next_task(["medium"])
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
9
25
|
describe "add_task" do
|
10
26
|
it "returns true when skill present" do
|
11
27
|
@queue.add_task(5)
|
@@ -53,20 +53,20 @@ describe 'Coordinator::RedisQueue' do
|
|
53
53
|
end
|
54
54
|
|
55
55
|
describe '.remove' do
|
56
|
-
it 'returns
|
56
|
+
it 'returns true when element found and removes' do
|
57
57
|
@queue.push(1)
|
58
|
-
assert_equal
|
58
|
+
assert_equal true, @queue.remove(1)
|
59
59
|
assert_equal 0, @queue.length
|
60
60
|
end
|
61
61
|
|
62
|
-
it 'returns
|
62
|
+
it 'returns false when element not found' do
|
63
63
|
@queue.push(1)
|
64
|
-
assert_equal
|
64
|
+
assert_equal false, @queue.remove(4)
|
65
65
|
assert_equal 1, @queue.length
|
66
66
|
end
|
67
67
|
|
68
|
-
it 'returns
|
69
|
-
assert_equal
|
68
|
+
it 'returns false when queue empty' do
|
69
|
+
assert_equal false, @queue.remove(4)
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
@@ -77,6 +77,10 @@ describe 'Coordinator::RedisQueue' do
|
|
77
77
|
assert_equal 1, @queue.peek
|
78
78
|
assert_equal 2, @queue.length
|
79
79
|
end
|
80
|
+
|
81
|
+
it 'return nil if no items' do
|
82
|
+
assert_equal nil, @queue.peek
|
83
|
+
end
|
80
84
|
end
|
81
85
|
|
82
86
|
describe '.capacity' do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: coordinator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tyler Mercier
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-03-
|
11
|
+
date: 2014-03-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: http
|
@@ -103,6 +103,7 @@ files:
|
|
103
103
|
- lib/coordinator/version.rb
|
104
104
|
- test/test_helper.rb
|
105
105
|
- test/unit/base_test.rb
|
106
|
+
- test/unit/parallelism_test.rb
|
106
107
|
- test/unit/queue_test.rb
|
107
108
|
- test/unit/redis_queue_test.rb
|
108
109
|
homepage: ''
|
@@ -132,5 +133,6 @@ summary: Ruby gem for coordinating multiple redis queues
|
|
132
133
|
test_files:
|
133
134
|
- test/test_helper.rb
|
134
135
|
- test/unit/base_test.rb
|
136
|
+
- test/unit/parallelism_test.rb
|
135
137
|
- test/unit/queue_test.rb
|
136
138
|
- test/unit/redis_queue_test.rb
|