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