fairway 0.0.9 → 0.0.10

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- fairway (0.0.8)
4
+ fairway (0.0.9)
5
5
  activesupport
6
6
  hiredis
7
7
  redis
data/lib/fairway/queue.rb CHANGED
@@ -7,12 +7,28 @@ module Fairway
7
7
  @queue_names = parse_queue_names(queue_names)
8
8
  end
9
9
 
10
+ def active_facets
11
+ each_queue do |queue|
12
+ redis.smembers("#{queue}:active_facets")
13
+ end.flatten.uniq
14
+ end
15
+
10
16
  def length
11
- @connection.redis.mget(@queue_names.uniq.map{|q| "#{q}:length" }).sum.to_i
17
+ redis.mget(unique_queues.map{|q| "#{q}:length" }).sum.to_i
18
+ end
19
+
20
+ def facet_length(facet)
21
+ each_queue do |queue|
22
+ redis.llen("#{queue}:#{facet}")
23
+ end.sum
24
+ end
25
+
26
+ def peek
27
+ scripts.fairway_peek(@queue_names.shuffle.uniq)
12
28
  end
13
29
 
14
30
  def pull
15
- @connection.scripts.fairway_pull(@queue_names.shuffle.uniq)
31
+ scripts.fairway_pull(@queue_names.shuffle.uniq)
16
32
  end
17
33
 
18
34
  def ==(other)
@@ -24,6 +40,24 @@ module Fairway
24
40
 
25
41
  private
26
42
 
43
+ def unique_queues
44
+ @queue_names.uniq
45
+ end
46
+
47
+ def each_queue(&block)
48
+ unique_queues.map do |queue|
49
+ yield(queue)
50
+ end
51
+ end
52
+
53
+ def scripts
54
+ @connection.scripts
55
+ end
56
+
57
+ def redis
58
+ @connection.redis
59
+ end
60
+
27
61
  def parse_queue_names(names)
28
62
  [].tap do |queues|
29
63
  names.each do |name|
@@ -1,3 +1,3 @@
1
1
  module Fairway
2
- VERSION = "0.0.9"
2
+ VERSION = "0.0.10"
3
3
  end
@@ -0,0 +1,15 @@
1
+ local namespace = KEYS[1];
2
+
3
+ for index, queue_name in ipairs(ARGV) do
4
+ local active_facets = namespace .. queue_name .. ':active_facets';
5
+ local facet_queue = namespace .. queue_name .. ':facet_queue';
6
+
7
+ local facet = redis.call('lrange', facet_queue, -1, -1)[1];
8
+
9
+ if facet then
10
+ local message_queue = namespace .. queue_name .. ':' .. facet;
11
+ local message = redis.call('lrange', message_queue, -1, -1)[1];
12
+
13
+ return {queue_name, message};
14
+ end
15
+ end
@@ -8,7 +8,12 @@ module Fairway
8
8
  message[:topic]
9
9
  end
10
10
  end
11
- let(:message) { { facet: 1, topic: "event:helloworld" } }
11
+ let(:queue) { Queue.new(connection, "myqueue") }
12
+ let(:message) { { facet: 1, topic: "event:helloworld" } }
13
+
14
+ before do
15
+ Fairway.config.register_queue("myqueue", "event:helloworld")
16
+ end
12
17
 
13
18
  describe "#initialize" do
14
19
  it "requires a Connection and queue names" do
@@ -17,12 +22,6 @@ module Fairway
17
22
  end
18
23
 
19
24
  describe "#length" do
20
- let(:queue) { Queue.new(connection, "myqueue") }
21
-
22
- before do
23
- Fairway.config.register_queue("myqueue", "event:helloworld")
24
- end
25
-
26
25
  it "returns the number of queued messages across facets" do
27
26
  queue.length.should == 0
28
27
 
@@ -40,16 +39,82 @@ module Fairway
40
39
  end
41
40
  end
42
41
 
43
- describe "#pull" do
44
- before do
45
- Fairway.config.register_queue("myqueue", "event:helloworld")
42
+ describe "#active_facets" do
43
+ it "returns list of all facets who currently have messages" do
44
+ connection.deliver(message.merge(facet: 1, message: 1))
45
+ connection.deliver(message.merge(facet: 2, message: 2))
46
+ connection.deliver(message.merge(facet: 3, message: 3))
47
+
48
+ queue.pull
49
+
50
+ queue.active_facets.should == ["2", "3"]
51
+ end
52
+
53
+ context "multiple queues" do
54
+ let(:queue) { Queue.new(connection, "myqueue1", "myqueue2") }
55
+
56
+ before do
57
+ Fairway.config.register_queue("myqueue1", "event:1")
58
+ Fairway.config.register_queue("myqueue2", "event:2")
59
+ end
60
+
61
+ it "returns list of all facets from multiple queues" do
62
+ connection.deliver(message.merge(topic: "event:1", facet: 1, message: 1))
63
+ connection.deliver(message.merge(topic: "event:1", facet: 2, message: 2))
64
+ connection.deliver(message.merge(topic: "event:1", facet: 3, message: 2))
65
+ connection.deliver(message.merge(topic: "event:2", facet: 3, message: 3))
66
+
67
+ queue.active_facets.should == ["1", "2", "3"]
68
+ end
69
+ end
70
+ end
71
+
72
+ describe "#facet_length" do
73
+ it "returns number of messages queues for a given facet" do
74
+ connection.deliver(message.merge(facet: 1, message: 1))
75
+ connection.deliver(message.merge(facet: 1, message: 2))
76
+ connection.deliver(message.merge(facet: 2, message: 3))
77
+
78
+ queue.facet_length(1).should == 2
79
+ queue.facet_length(2).should == 1
80
+ queue.facet_length(3).should == 0
81
+ end
82
+
83
+ context "multiple queues" do
84
+ let(:queue) { Queue.new(connection, "myqueue1", "myqueue2") }
85
+
86
+ before do
87
+ Fairway.config.register_queue("myqueue1", "event:1")
88
+ Fairway.config.register_queue("myqueue2", "event:2")
89
+ end
90
+
91
+ it "sums number of messages for facet across all queues" do
92
+ connection.deliver(message.merge(topic: "event:1", facet: 1, message: 1))
93
+ connection.deliver(message.merge(topic: "event:1", facet: 2, message: 2))
94
+ connection.deliver(message.merge(topic: "event:1", facet: 3, message: 2))
95
+ connection.deliver(message.merge(topic: "event:2", facet: 3, message: 3))
96
+
97
+ queue.facet_length(1).should == 1
98
+ queue.facet_length(2).should == 1
99
+ queue.facet_length(3).should == 2
100
+ end
101
+ end
102
+ end
103
+
104
+ describe "#peek" do
105
+ it "returns, but doesn't remove the next message to be pulled" do
106
+ connection.deliver(message1 = message.merge(message: 1))
107
+ queue.peek.should == ["myqueue", message1.to_json]
108
+ queue.pull.should == ["myqueue", message1.to_json]
109
+ queue.pull.should be_nil
46
110
  end
111
+ end
47
112
 
113
+ describe "#pull" do
48
114
  it "pulls a message off the queue using FIFO strategy" do
49
115
  connection.deliver(message1 = message.merge(message: 1))
50
116
  connection.deliver(message2 = message.merge(message: 2))
51
117
 
52
- queue = Queue.new(connection, "myqueue")
53
118
  queue.pull.should == ["myqueue", message1.to_json]
54
119
  queue.pull.should == ["myqueue", message2.to_json]
55
120
  end
@@ -59,7 +124,6 @@ module Fairway
59
124
  connection.deliver(message2 = message.merge(facet: 1, message: 2))
60
125
  connection.deliver(message3 = message.merge(facet: 2, message: 3))
61
126
 
62
- queue = Queue.new(connection, "myqueue")
63
127
  queue.pull.should == ["myqueue", message1.to_json]
64
128
  queue.pull.should == ["myqueue", message3.to_json]
65
129
  queue.pull.should == ["myqueue", message2.to_json]
@@ -68,21 +132,21 @@ module Fairway
68
132
  it "removes facet from active list if it becomes empty" do
69
133
  connection.deliver(message)
70
134
 
71
- Fairway.config.redis.smembers("myqueue:active_facets").should == ["1"]
72
- queue = Queue.new(connection, "myqueue")
135
+ queue.active_facets.should == ["1"]
73
136
  queue.pull
74
- Fairway.config.redis.smembers("myqueue:active_facets").should be_empty
137
+ queue.active_facets.should be_empty
75
138
  end
76
139
 
77
140
  it "returns nil if there are no messages to retrieve" do
78
141
  connection.deliver(message)
79
142
 
80
- queue = Queue.new(connection, "myqueue")
81
143
  queue.pull.should == ["myqueue", message.to_json]
82
144
  queue.pull.should be_nil
83
145
  end
84
146
 
85
147
  context "pulling from multiple queues" do
148
+ let(:queue) { Queue.new(connection, "myqueue2", "myqueue1") }
149
+
86
150
  before do
87
151
  Fairway.config.register_queue("myqueue1", "event:1")
88
152
  Fairway.config.register_queue("myqueue2", "event:2")
@@ -92,16 +156,12 @@ module Fairway
92
156
  connection.deliver(message1 = message.merge(topic: "event:1"))
93
157
  connection.deliver(message2 = message.merge(topic: "event:2"))
94
158
 
95
- queue = Queue.new(connection, "myqueue2", "myqueue1")
96
-
97
159
  messages = [["myqueue1", message1.to_json], ["myqueue2", message2.to_json]]
98
160
  messages.should include(queue.pull)
99
161
  messages.should include(queue.pull)
100
162
  end
101
163
 
102
164
  it "randomized order of queues attempted to reduce starvation" do
103
- queue = Queue.new(connection, "myqueue2", "myqueue1")
104
-
105
165
  order = {}
106
166
 
107
167
  queue.connection.scripts.stub(:fairway_pull) do |queues|
@@ -137,7 +197,6 @@ module Fairway
137
197
  end
138
198
 
139
199
  it "returns nil if no queues have messages" do
140
- queue = Queue.new(connection, "myqueue2", "myqueue1")
141
200
  queue.pull.should be_nil
142
201
  end
143
202
 
@@ -148,7 +207,6 @@ module Fairway
148
207
  connection.deliver(message4 = message.merge(facet: 1, topic: "event:2"))
149
208
 
150
209
  queue1_messages = []
151
- queue = Queue.new(connection, "myqueue2", "myqueue1")
152
210
 
153
211
  4.times do
154
212
  message = queue.pull
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fairway
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.9
4
+ version: 0.0.10
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: 2013-04-08 00:00:00.000000000 Z
12
+ date: 2013-04-21 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -102,6 +102,7 @@ files:
102
102
  - lib/fairway/sidekiq/fetch.rb
103
103
  - lib/fairway/version.rb
104
104
  - redis/fairway_deliver.lua
105
+ - redis/fairway_peek.lua
105
106
  - redis/fairway_pull.lua
106
107
  - spec/lib/fairway/channeled_connection_spec.rb
107
108
  - spec/lib/fairway/config_spec.rb