coordinator 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 480787ac7b5eecf9271ec542f15f5ebf17d23085
4
- data.tar.gz: 9f688ebfcd97125c0292784f8ab06a121b9a4b51
3
+ metadata.gz: e53824a57bc5054c529d8a0566a4c26024fb9eaf
4
+ data.tar.gz: 7db6d332ac9d662721a5c45cb2e0ca52493cf1cf
5
5
  SHA512:
6
- metadata.gz: c4ee690d00d2e78c10636c587c6f701230822c85a43118ab8c605759c4f9f2c75130f773649f2671ea1a4af2a6674d9643bc2be958c3dafbe21c5cc6acac4375
7
- data.tar.gz: 7b4742110498118ffcf39ad32e72b98c55bb8957d3df4f4b67fc065abe705e73a1d00ce2e60018f18839598afc228dbe0d3359830eea5e007a9b6cb83b1a473f
6
+ metadata.gz: ac992d700929b4d5ae35ddabfff494280e77daacc25198e1d2a07fb9be322d7eaea7a9849ec933dfb40eb7532d98530ae47c2200d036caedc9249c241ae11a89
7
+ data.tar.gz: 672e70f26491333ebbabbd33a2692125dfc9af2875aca218b4b7f3b8e491bd4edf8433ef8d5826ca92a6a841986d31e97f7aa750bbb0c2a7a62e4f7da439f6f9
data/README.md CHANGED
@@ -28,6 +28,13 @@ Or install it yourself as:
28
28
  Coordinator::Queue.new("medium"),
29
29
  Coordinator::Queue.new("low")
30
30
  ])
31
+
32
+ @coordinator.add_task("high", 1)
33
+ @coordinator.add_task("medium", 2)
34
+ @coordinator.add_priority_task("high", 3)
35
+
36
+ @coordinator.next_task(["high"]) # returns 3
37
+ @coordinator.next_task(["medium"]) # returns 2
31
38
 
32
39
  ## Contributing
33
40
 
@@ -1,4 +1,5 @@
1
1
  require "coordinator/version"
2
+ require "coordinator/error"
2
3
  require "coordinator/redis_queue"
3
4
  require "coordinator/queue"
4
5
  require "coordinator/base"
@@ -22,11 +22,16 @@ module Coordinator
22
22
  false
23
23
  end
24
24
 
25
+ def set_capacity(skill, capacity)
26
+ queue = queue_for_skill(skill)
27
+ queue.set_capacity(capacity)
28
+ end
29
+
25
30
  private
26
31
 
27
32
  def queue_for_skill(skill)
28
33
  queue = @queues.find {|q| q.skill == skill}
29
- raise "No matching queue for #{skill}" unless queue
34
+ raise Coordinator::Error.new("No matching queue for #{skill}") unless queue
30
35
  queue
31
36
  end
32
37
  end
@@ -0,0 +1,4 @@
1
+ module Coordinator
2
+ class Error < Exception
3
+ end
4
+ end
@@ -1,10 +1,12 @@
1
1
  module Coordinator
2
2
  class Queue
3
- attr_reader :skill
3
+ attr_reader :skill, :rules
4
4
 
5
- def initialize(skill)
5
+ def initialize(skill, capacity=nil, &block)
6
6
  @skill = skill
7
7
  @store = Coordinator::RedisQueue.new(@skill)
8
+ @store.capacity = capacity if capacity
9
+ @custom_block = block if block_given?
8
10
  end
9
11
 
10
12
  def add_task(task)
@@ -16,11 +18,16 @@ module Coordinator
16
18
  end
17
19
 
18
20
  def next_task(skills)
19
- can_work?(skills) ? @store.pop : nil
21
+ eligible?(@store.peek, skills) ? @store.pop : nil
20
22
  end
21
23
 
22
- def can_work?(skills)
23
- skills.include?(@skill)
24
+ def eligible?(task, skills)
25
+ return true if skills.include?(@skill)
26
+ @custom_block ? @custom_block.call(task, skills) : false
27
+ end
28
+
29
+ def set_capacity(capacity)
30
+ @store.capacity = capacity
24
31
  end
25
32
  end
26
33
  end
@@ -3,44 +3,60 @@ require 'json'
3
3
  module Coordinator
4
4
  class RedisQueue
5
5
  def initialize(name)
6
- @name = name
7
- raise "redis not found, please set 'Redis.current'" unless Redis.current
6
+ @queue_name = "#{name}-queue"
7
+ @capacity_name = "#{name}-capacity"
8
+ raise Coordinator::Error.new("'Redis.current' not set") unless Redis.current
8
9
  @redis = Redis.current
9
10
  end
10
11
 
11
12
  def push(item)
13
+ raise Coordinator::Error.new("Queue is at capacity") if full?
12
14
  data = serialize(item)
13
- @redis.rpush(@name, data) unless items.include?(data)
15
+ @redis.rpush(@queue_name, data) unless items.include?(data)
14
16
  end
15
17
 
16
18
  def left_push(item)
17
19
  data = serialize(item)
18
- @redis.lpush(@name, data) unless items.include?(data)
20
+ @redis.lpush(@queue_name, data) unless items.include?(data)
19
21
  end
20
22
 
21
23
  def pop
22
- data = @redis.lpop(@name)
24
+ data = @redis.lpop(@queue_name)
23
25
  parse(data)
24
26
  end
25
27
 
26
28
  def remove(item)
27
29
  data = serialize(item)
28
- @redis.lrem(@name, 1, data)
30
+ @redis.lrem(@queue_name, 1, data)
29
31
  end
30
32
 
31
33
  def peek
32
- data = @redis.lrange(@name, 0, 0).first
34
+ data = @redis.lrange(@queue_name, 0, 0).first
33
35
  parse(data)
34
36
  end
35
37
 
36
38
  def length
37
- @redis.llen(@name)
39
+ @redis.llen(@queue_name)
40
+ end
41
+
42
+ def capacity
43
+ data = @redis.get(@capacity_name)
44
+ parse(data)
45
+ end
46
+
47
+ def capacity=(capacity)
48
+ @redis.set(@capacity_name, capacity)
38
49
  end
39
50
 
40
51
  private
41
52
 
53
+ def full?
54
+ return false unless capacity
55
+ length >= capacity
56
+ end
57
+
42
58
  def items
43
- @redis.lrange(@name, 0, length)
59
+ @redis.lrange(@queue_name, 0, length)
44
60
  end
45
61
 
46
62
  def serialize(item)
@@ -1,3 +1,3 @@
1
1
  module Coordinator
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -1,8 +1,7 @@
1
1
  require 'minitest/autorun'
2
2
  require 'minitest/reporters'
3
- require "fakeredis"
3
+ require 'fakeredis'
4
4
 
5
- Redis.current = Redis.new
6
5
  Minitest::Reporters.use!(Minitest::Reporters::DefaultReporter.new(color: true))
7
6
 
8
7
  ENV['RACK_ENV'] = 'test'
@@ -19,5 +19,12 @@ describe 'Coordinator::Base' do
19
19
  assert_equal 2, @coordinator.next_task(["medium"])
20
20
  assert_equal false, @coordinator.next_task(["medium"])
21
21
  end
22
+
23
+ it 'raises exception when no queue exists' do
24
+ err = -> {
25
+ @coordinator.add_task("forgotten", 1)
26
+ }.must_raise Coordinator::Error
27
+ err.message.must_match /No matching queue for forgotten/
28
+ end
22
29
  end
23
30
  end
@@ -24,13 +24,26 @@ describe "Coordinator::Queue" do
24
24
  end
25
25
  end
26
26
 
27
- describe "can_work?" do
27
+ describe "eligible?" do
28
28
  it "returns true when skill present" do
29
- assert @queue.can_work?(["high"])
29
+ assert @queue.eligible?(nil, ["high"])
30
30
  end
31
31
 
32
32
  it "returns false when skill not present" do
33
- refute @queue.can_work?(["general", "rogers"])
33
+ refute @queue.eligible?(nil, ["low", "normal"])
34
+ end
35
+
36
+ it "can override default behaviour" do
37
+ queue = Coordinator::Queue.new("normal") do |task, skills|
38
+ return true if skills.include?("low")
39
+ return true if task == 4
40
+ task == 3 && skills.include?("special")
41
+ end
42
+ refute queue.eligible?(2, ["special"])
43
+ assert queue.eligible?(nil, ["normal"]), "default behaviour"
44
+ assert queue.eligible?(2, ["low"]), "override through skill"
45
+ assert queue.eligible?(4, []), "override through task"
46
+ assert queue.eligible?(3, ["special"]), "override through both"
34
47
  end
35
48
  end
36
49
  end
@@ -18,6 +18,15 @@ describe 'Coordinator::RedisQueue' do
18
18
  @queue.push("a")
19
19
  assert_equal 1, @queue.length
20
20
  end
21
+
22
+ it 'adds the same item only once' do
23
+ @queue.capacity = 1
24
+ @queue.push("a")
25
+ err = -> {
26
+ @queue.push("b")
27
+ }.must_raise Coordinator::Error
28
+ err.message.must_match /Queue is at capacity/
29
+ end
21
30
  end
22
31
 
23
32
  describe '.left_push' do
@@ -70,6 +79,14 @@ describe 'Coordinator::RedisQueue' do
70
79
  end
71
80
  end
72
81
 
82
+ describe '.capacity' do
83
+ it 'gets the top item and does not remove' do
84
+ assert_equal nil, @queue.capacity
85
+ @queue.capacity = 2
86
+ assert_equal 2, @queue.capacity
87
+ end
88
+ end
89
+
73
90
  it 'allows for objects' do
74
91
  [1000, "taco", {"a" => 1}, [1,2,3]].each do |o|
75
92
  @queue.push(o)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: coordinator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tyler Mercier
@@ -97,6 +97,7 @@ files:
97
97
  - coordinator.gemspec
98
98
  - lib/coordinator.rb
99
99
  - lib/coordinator/base.rb
100
+ - lib/coordinator/error.rb
100
101
  - lib/coordinator/queue.rb
101
102
  - lib/coordinator/redis_queue.rb
102
103
  - lib/coordinator/version.rb