fairway 0.0.9 → 0.0.10

Sign up to get free protection for your applications and to get access to all the features.
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