coordinator 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e53824a57bc5054c529d8a0566a4c26024fb9eaf
4
- data.tar.gz: 7db6d332ac9d662721a5c45cb2e0ca52493cf1cf
3
+ metadata.gz: d30f4f717a647bb842456b00f951a25f613492ab
4
+ data.tar.gz: 96401cd4398ef8040044a89a711bbb77d3831f80
5
5
  SHA512:
6
- metadata.gz: ac992d700929b4d5ae35ddabfff494280e77daacc25198e1d2a07fb9be322d7eaea7a9849ec933dfb40eb7532d98530ae47c2200d036caedc9249c241ae11a89
7
- data.tar.gz: 672e70f26491333ebbabbd33a2692125dfc9af2875aca218b4b7f3b8e491bd4edf8433ef8d5826ca92a6a841986d31e97f7aa750bbb0c2a7a62e4f7da439f6f9
6
+ metadata.gz: 351d5200dc09beff1d9f3060fbb89fbbeec754aa83289ccc9ed23951e3e50571e78215989b79ae713dbc4ac189a15dba9d0eff333e208be311b8a9f8a7e72fa5
7
+ data.tar.gz: 4c1d21850138d1ca67c5f820dc977243ce8f4f28473a8efa8b57da88c04306285da85e26ae59ece072993f9eafb0ac27202d2e9a36cea2051fcb7b30060196c0
@@ -5,13 +5,15 @@ module Coordinator
5
5
  end
6
6
 
7
7
  def add_task(skill, task)
8
- queue = queue_for_skill(skill)
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
- queue = queue_for_skill(skill)
14
- queue.add_priority_task(task)
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
- queue.set_capacity(capacity)
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.new("No matching queue for #{skill}") unless queue
45
+ raise Coordinator::Error, "No matching queue for #{skill}" unless queue
35
46
  queue
36
47
  end
37
48
  end
@@ -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
- eligible?(@store.peek, skills) ? @store.pop : nil
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.new("'Redis.current' not set") unless Redis.current
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.new("Queue is at capacity") if full?
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
- return false unless capacity
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)
@@ -1,3 +1,3 @@
1
1
  module Coordinator
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -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
@@ -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 1 when element found and removes' do
56
+ it 'returns true when element found and removes' do
57
57
  @queue.push(1)
58
- assert_equal 1, @queue.remove(1)
58
+ assert_equal true, @queue.remove(1)
59
59
  assert_equal 0, @queue.length
60
60
  end
61
61
 
62
- it 'returns 0 when element not found' do
62
+ it 'returns false when element not found' do
63
63
  @queue.push(1)
64
- assert_equal 0, @queue.remove(4)
64
+ assert_equal false, @queue.remove(4)
65
65
  assert_equal 1, @queue.length
66
66
  end
67
67
 
68
- it 'returns nil when queue empty' do
69
- assert_equal nil, @queue.remove(4)
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.2
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-25 00:00:00.000000000 Z
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