fairway 0.3.1 → 0.3.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 +8 -8
- data/Gemfile +2 -0
- data/Gemfile.lock +3 -2
- data/go/fairway_ack.go +2 -1
- data/go/fairway_deliver.go +0 -1
- data/go/fairway_pull.go +89 -56
- data/go/message.go +2 -1
- data/go/queue_test.go +81 -0
- data/lib/fairway/version.rb +1 -1
- data/redis/fairway_deliver.lua +0 -1
- data/redis/fairway_pull.lua +90 -56
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
ODBhZmUyMTQyYmZkMTk0ZmJkNGM3ZmQ4ZjdkZWUzNzc5MjRlMTE3Nw==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
MzcxMWQxYjFkMzVhYTY4M2Y1M2M0YjRlY2NlZGU0YzVjYjIwZjFmNA==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
NGE4NmM1Yzk5NGE2NzYxNTdiNjIxYzQzZDU3ZjZiZmVjNjNkYjZmNTNjNDUz
|
10
|
+
Y2IwNmViOTgxNmU5NjAzM2U2OTE2MWJmNTk1YTEyYWVmZWEyMDFlZmI2NDgy
|
11
|
+
NDE5OTJiNDk1YTY5YTRlMDNiODFmNWU2YTQ3ODZiZjE3MjA0YWU=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
MDEwZDIwMzI0YzQ4Yzc0NDU2NWRkNzMxOGM5ZjkxMjMwY2I5NGFiYmU2NTE0
|
14
|
+
NjA1YTAxMmNmZjNmNjEzNWJmZWFlMjBkNzljZmVjZDZkYmY4YTQwODFiMWMy
|
15
|
+
NDFjZjA1OTNhZTc0MWM5YmVmZjU0MzMxMjRkMGEzNmE0MzRjNWQ=
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
fairway (0.
|
5
|
-
activesupport
|
4
|
+
fairway (0.3.1)
|
5
|
+
activesupport
|
6
6
|
connection_pool
|
7
7
|
redis
|
8
8
|
redis-namespace (>= 1.3.0)
|
@@ -51,6 +51,7 @@ PLATFORMS
|
|
51
51
|
ruby
|
52
52
|
|
53
53
|
DEPENDENCIES
|
54
|
+
activesupport (= 4.0.2)
|
54
55
|
fairway!
|
55
56
|
rake
|
56
57
|
rspec
|
data/go/fairway_ack.go
CHANGED
@@ -49,8 +49,9 @@ if removed > 0 then
|
|
49
49
|
redis.call('hset', facet_pool, facet, current + 1);
|
50
50
|
end
|
51
51
|
|
52
|
-
if (
|
52
|
+
if (length == 0 and inflight_cur == 0 and n == 0) then
|
53
53
|
redis.call('del', inflight_total);
|
54
|
+
redis.call('hdel', facet_pool, facet);
|
54
55
|
redis.call('srem', active_facets, facet);
|
55
56
|
end
|
56
57
|
end
|
data/go/fairway_deliver.go
CHANGED
@@ -36,7 +36,6 @@ for i = 1, #registered_queues, 2 do
|
|
36
36
|
local length = redis.call('lpush', k(queue, facet), message)
|
37
37
|
redis.call('incr', k(queue, 'length'));
|
38
38
|
|
39
|
-
|
40
39
|
-- Manage facet queue and active facets
|
41
40
|
local current = tonumber(redis.call('hget', facet_pool, facet)) or 0;
|
42
41
|
local priority = tonumber(redis.call('hget', priorities, facet)) or 1;
|
data/go/fairway_pull.go
CHANGED
@@ -10,38 +10,15 @@ local k = function (queue, subkey)
|
|
10
10
|
return namespace .. queue .. ':' .. subkey;
|
11
11
|
end
|
12
12
|
|
13
|
-
|
14
|
-
-- fairway_pull. We'll loop through all
|
15
|
-
-- provided queues, and return a message
|
16
|
-
-- from the first one that isn't empty.
|
17
|
-
for i, queue in ipairs(ARGV) do
|
18
|
-
local active_facets = k(queue, 'active_facets');
|
13
|
+
local pull = function (queue)
|
19
14
|
local round_robin = k(queue, 'facet_queue');
|
20
15
|
local inflight = k(queue, 'inflight');
|
21
|
-
local inflight_limit = k(queue, 'limit');
|
22
|
-
local priorities = k(queue, 'priorities');
|
23
|
-
local facet_pool = k(queue, 'facet_pool');
|
24
|
-
|
25
|
-
if wait ~= -1 then
|
26
|
-
-- Check if any current inflight messages
|
27
|
-
-- have been inflight for a long time.
|
28
|
-
local inflightmessage = redis.call('zrange', inflight, 0, 0, 'WITHSCORES');
|
29
|
-
|
30
|
-
-- If we have an inflight message and it's score
|
31
|
-
-- is less than the current pull timestamp, reset
|
32
|
-
-- the inflight score for the the message and resend.
|
33
|
-
if #inflightmessage > 0 then
|
34
|
-
if tonumber(inflightmessage[2]) <= timestamp then
|
35
|
-
redis.call('zadd', inflight, timestamp + wait, inflightmessage[1]);
|
36
|
-
return {queue, inflightmessage[1]}
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
16
|
|
41
17
|
-- Pull a facet from the round-robin list.
|
42
18
|
-- This list guarantees each active facet will have a
|
43
19
|
-- message pulled from the queue every time through..
|
44
20
|
local facet = redis.call('rpop', round_robin);
|
21
|
+
local message = nil
|
45
22
|
|
46
23
|
if facet then
|
47
24
|
-- If we found an active facet, we know the facet
|
@@ -50,7 +27,7 @@ for i, queue in ipairs(ARGV) do
|
|
50
27
|
local messages = k(queue, facet);
|
51
28
|
local inflight_total = k(queue, facet .. ':inflight');
|
52
29
|
|
53
|
-
|
30
|
+
message = redis.call('rpop', messages);
|
54
31
|
|
55
32
|
if message then
|
56
33
|
if wait ~= -1 then
|
@@ -60,43 +37,99 @@ for i, queue in ipairs(ARGV) do
|
|
60
37
|
|
61
38
|
redis.call('decr', k(queue, 'length'));
|
62
39
|
end
|
40
|
+
end
|
63
41
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
42
|
+
return {facet, message};
|
43
|
+
end
|
44
|
+
|
45
|
+
local manage = function (queue, facet)
|
46
|
+
local active_facets = k(queue, 'active_facets');
|
47
|
+
local round_robin = k(queue, 'facet_queue');
|
48
|
+
local inflight_limit = k(queue, 'limit');
|
49
|
+
local priorities = k(queue, 'priorities');
|
50
|
+
local facet_pool = k(queue, 'facet_pool');
|
51
|
+
local messages = k(queue, facet);
|
52
|
+
local inflight_total = k(queue, facet .. ':inflight');
|
53
|
+
|
54
|
+
local current = tonumber(redis.call('hget', facet_pool, facet)) or 0;
|
55
|
+
local priority = tonumber(redis.call('hget', priorities, facet)) or 1;
|
56
|
+
local length = redis.call('llen', messages);
|
57
|
+
local inflight_cur = tonumber(redis.call('get', inflight_total)) or 0;
|
58
|
+
local inflight_max = tonumber(redis.call('get', inflight_limit)) or 0;
|
59
|
+
|
60
|
+
local n = 0
|
61
|
+
|
62
|
+
-- redis.log(redis.LOG_WARNING, current.."/"..length.."/"..priority.."/"..inflight_max.."/"..inflight_cur);
|
63
|
+
|
64
|
+
if inflight_max > 0 then
|
65
|
+
n = math.min(length, priority, inflight_max - inflight_cur);
|
66
|
+
else
|
67
|
+
n = math.min(length, priority);
|
68
|
+
end
|
69
|
+
|
70
|
+
-- redis.log(redis.LOG_WARNING, "PULL: "..current.."/"..n);
|
71
|
+
|
72
|
+
if n < current then
|
73
|
+
-- redis.log(redis.LOG_WARNING, "shrinking");
|
74
|
+
redis.call('hset', facet_pool, facet, current - 1);
|
75
|
+
elseif n > current then
|
76
|
+
-- redis.log(redis.LOG_WARNING, "growing");
|
77
|
+
redis.call('lpush', round_robin, facet);
|
78
|
+
redis.call('lpush', round_robin, facet);
|
79
|
+
redis.call('hset', facet_pool, facet, current + 1);
|
80
|
+
else
|
81
|
+
-- redis.log(redis.LOG_WARNING, "maintaining");
|
82
|
+
redis.call('lpush', round_robin, facet);
|
83
|
+
end
|
84
|
+
|
85
|
+
if (length == 0 and inflight_cur == 0 and n == 0) then
|
86
|
+
redis.call('del', inflight_total);
|
87
|
+
redis.call('hdel', facet_pool, facet);
|
88
|
+
redis.call('srem', active_facets, facet);
|
89
|
+
end
|
90
|
+
end
|
70
91
|
|
71
|
-
|
92
|
+
-- Multiple queues can be passed through
|
93
|
+
-- fairway_pull. We'll loop through all
|
94
|
+
-- provided queues, and return a message
|
95
|
+
-- from the first one that isn't empty.
|
96
|
+
for i, queue in ipairs(ARGV) do
|
97
|
+
local inflight = k(queue, 'inflight');
|
72
98
|
|
73
|
-
|
99
|
+
if wait ~= -1 then
|
100
|
+
-- Check if any current inflight messages
|
101
|
+
-- have been inflight for a long time.
|
102
|
+
local inflightmessage = redis.call('zrange', inflight, 0, 0, 'WITHSCORES');
|
74
103
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
104
|
+
-- If we have an inflight message and it's score
|
105
|
+
-- is less than the current pull timestamp, reset
|
106
|
+
-- the inflight score for the the message and resend.
|
107
|
+
if #inflightmessage > 0 then
|
108
|
+
if tonumber(inflightmessage[2]) <= timestamp then
|
109
|
+
redis.call('zadd', inflight, timestamp + wait, inflightmessage[1]);
|
110
|
+
return {queue, inflightmessage[1]}
|
111
|
+
end
|
79
112
|
end
|
113
|
+
end
|
80
114
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
-- redis.log(redis.LOG_WARNING, "shrinking");
|
85
|
-
redis.call('hset', facet_pool, facet, current - 1);
|
86
|
-
elseif n > current then
|
87
|
-
-- redis.log(redis.LOG_WARNING, "growing");
|
88
|
-
redis.call('lpush', round_robin, facet);
|
89
|
-
redis.call('lpush', round_robin, facet);
|
90
|
-
redis.call('hset', facet_pool, facet, current + 1);
|
91
|
-
else
|
92
|
-
-- redis.log(redis.LOG_WARNING, "maintaining");
|
93
|
-
redis.call('lpush', round_robin, facet);
|
94
|
-
end
|
115
|
+
local pulled = pull(queue);
|
116
|
+
local facet = pulled[1];
|
117
|
+
local message = pulled[2];
|
95
118
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
119
|
+
if facet then
|
120
|
+
manage(queue, facet);
|
121
|
+
|
122
|
+
-- if message then
|
123
|
+
-- else
|
124
|
+
-- -- TODO loop through until we find a message
|
125
|
+
-- pulled = pull(queue);
|
126
|
+
-- facet = pulled[1];
|
127
|
+
-- message = pulled[2];
|
128
|
+
|
129
|
+
-- if facet then
|
130
|
+
-- manage(queue, facet);
|
131
|
+
-- end
|
132
|
+
-- end
|
100
133
|
|
101
134
|
return {queue, message};
|
102
135
|
end
|
data/go/message.go
CHANGED
data/go/queue_test.go
CHANGED
@@ -62,6 +62,87 @@ func QueueSpec(c gospec.Context) {
|
|
62
62
|
c.Expect(message.json(), Equals, msg2.json())
|
63
63
|
})
|
64
64
|
|
65
|
+
c.Specify("skips over facets in invalid state", func() {
|
66
|
+
config.Facet = func(msg *Msg) string {
|
67
|
+
str, _ := msg.Get("facet").String()
|
68
|
+
return str
|
69
|
+
}
|
70
|
+
|
71
|
+
msg1, _ := NewMsg(map[string]string{"facet": "1", "name": "mymessage1"})
|
72
|
+
msg2, _ := NewMsg(map[string]string{"facet": "2", "name": "mymessage2"})
|
73
|
+
msg3, _ := NewMsg(map[string]string{"facet": "1", "name": "mymessage3"})
|
74
|
+
|
75
|
+
conn.Deliver(msg1)
|
76
|
+
conn.Deliver(msg2)
|
77
|
+
conn.Deliver(msg3)
|
78
|
+
|
79
|
+
r := config.Pool.Get()
|
80
|
+
defer r.Close()
|
81
|
+
|
82
|
+
count, _ := redis.Int(r.Do("llen", "fairway:myqueue:1"))
|
83
|
+
c.Expect(count, Equals, 2)
|
84
|
+
count, _ = redis.Int(r.Do("llen", "fairway:myqueue:2"))
|
85
|
+
c.Expect(count, Equals, 1)
|
86
|
+
count, _ = redis.Int(r.Do("scard", "fairway:myqueue:active_facets"))
|
87
|
+
c.Expect(count, Equals, 2)
|
88
|
+
count, _ = redis.Int(r.Do("llen", "fairway:myqueue:facet_queue"))
|
89
|
+
c.Expect(count, Equals, 2)
|
90
|
+
count, _ = redis.Int(r.Do("hget", "fairway:myqueue:facet_pool", "1"))
|
91
|
+
c.Expect(count, Equals, 1)
|
92
|
+
count, _ = redis.Int(r.Do("hget", "fairway:myqueue:facet_pool", "2"))
|
93
|
+
c.Expect(count, Equals, 1)
|
94
|
+
|
95
|
+
queueName, message := queue.Pull(-1)
|
96
|
+
c.Expect(queueName, Equals, "myqueue")
|
97
|
+
c.Expect(message.json(), Equals, msg1.json())
|
98
|
+
|
99
|
+
count, _ = redis.Int(r.Do("llen", "fairway:myqueue:1"))
|
100
|
+
c.Expect(count, Equals, 1)
|
101
|
+
count, _ = redis.Int(r.Do("llen", "fairway:myqueue:2"))
|
102
|
+
c.Expect(count, Equals, 1)
|
103
|
+
count, _ = redis.Int(r.Do("scard", "fairway:myqueue:active_facets"))
|
104
|
+
c.Expect(count, Equals, 2)
|
105
|
+
count, _ = redis.Int(r.Do("llen", "fairway:myqueue:facet_queue"))
|
106
|
+
c.Expect(count, Equals, 2)
|
107
|
+
count, _ = redis.Int(r.Do("hget", "fairway:myqueue:facet_pool", "1"))
|
108
|
+
c.Expect(count, Equals, 1)
|
109
|
+
count, _ = redis.Int(r.Do("hget", "fairway:myqueue:facet_pool", "2"))
|
110
|
+
c.Expect(count, Equals, 1)
|
111
|
+
|
112
|
+
// We expect a message to be in here
|
113
|
+
r.Do("del", "fairway:myqueue:2")
|
114
|
+
|
115
|
+
count, _ = redis.Int(r.Do("llen", "fairway:myqueue:1"))
|
116
|
+
c.Expect(count, Equals, 1)
|
117
|
+
count, _ = redis.Int(r.Do("llen", "fairway:myqueue:2"))
|
118
|
+
c.Expect(count, Equals, 0)
|
119
|
+
count, _ = redis.Int(r.Do("scard", "fairway:myqueue:active_facets"))
|
120
|
+
c.Expect(count, Equals, 2)
|
121
|
+
count, _ = redis.Int(r.Do("llen", "fairway:myqueue:facet_queue"))
|
122
|
+
c.Expect(count, Equals, 2)
|
123
|
+
count, _ = redis.Int(r.Do("hget", "fairway:myqueue:facet_pool", "1"))
|
124
|
+
c.Expect(count, Equals, 1)
|
125
|
+
count, _ = redis.Int(r.Do("hget", "fairway:myqueue:facet_pool", "2"))
|
126
|
+
c.Expect(count, Equals, 1)
|
127
|
+
|
128
|
+
queueName, message = queue.Pull(-1)
|
129
|
+
c.Expect(queueName, Equals, "myqueue")
|
130
|
+
c.Expect(message.json(), Equals, msg3.json())
|
131
|
+
|
132
|
+
count, _ = redis.Int(r.Do("llen", "fairway:myqueue:1"))
|
133
|
+
c.Expect(count, Equals, 0)
|
134
|
+
count, _ = redis.Int(r.Do("llen", "fairway:myqueue:2"))
|
135
|
+
c.Expect(count, Equals, 0)
|
136
|
+
count, _ = redis.Int(r.Do("scard", "fairway:myqueue:active_facets"))
|
137
|
+
c.Expect(count, Equals, 0)
|
138
|
+
count, _ = redis.Int(r.Do("llen", "fairway:myqueue:facet_queue"))
|
139
|
+
c.Expect(count, Equals, 0)
|
140
|
+
count, _ = redis.Int(r.Do("hget", "fairway:myqueue:facet_pool", "1"))
|
141
|
+
c.Expect(count, Equals, 0)
|
142
|
+
count, _ = redis.Int(r.Do("hget", "fairway:myqueue:facet_pool", "2"))
|
143
|
+
c.Expect(count, Equals, 0)
|
144
|
+
})
|
145
|
+
|
65
146
|
c.Specify("places pulled message on inflight sorted set until acknowledged", func() {
|
66
147
|
msg1, _ := NewMsg(map[string]string{"name": "mymessage1"})
|
67
148
|
|
data/lib/fairway/version.rb
CHANGED
data/redis/fairway_deliver.lua
CHANGED
@@ -32,7 +32,6 @@ for i = 1, #registered_queues, 2 do
|
|
32
32
|
local length = redis.call('lpush', k(queue, facet), message)
|
33
33
|
redis.call('incr', k(queue, 'length'));
|
34
34
|
|
35
|
-
|
36
35
|
-- Manage facet queue and active facets
|
37
36
|
local current = tonumber(redis.call('hget', facet_pool, facet)) or 0;
|
38
37
|
local priority = tonumber(redis.call('hget', priorities, facet)) or 1;
|
data/redis/fairway_pull.lua
CHANGED
@@ -6,38 +6,15 @@ local k = function (queue, subkey)
|
|
6
6
|
return namespace .. queue .. ':' .. subkey;
|
7
7
|
end
|
8
8
|
|
9
|
-
|
10
|
-
-- fairway_pull. We'll loop through all
|
11
|
-
-- provided queues, and return a message
|
12
|
-
-- from the first one that isn't empty.
|
13
|
-
for i, queue in ipairs(ARGV) do
|
14
|
-
local active_facets = k(queue, 'active_facets');
|
9
|
+
local pull = function (queue)
|
15
10
|
local round_robin = k(queue, 'facet_queue');
|
16
11
|
local inflight = k(queue, 'inflight');
|
17
|
-
local inflight_limit = k(queue, 'limit');
|
18
|
-
local priorities = k(queue, 'priorities');
|
19
|
-
local facet_pool = k(queue, 'facet_pool');
|
20
|
-
|
21
|
-
if wait ~= -1 then
|
22
|
-
-- Check if any current inflight messages
|
23
|
-
-- have been inflight for a long time.
|
24
|
-
local inflightmessage = redis.call('zrange', inflight, 0, 0, 'WITHSCORES');
|
25
|
-
|
26
|
-
-- If we have an inflight message and it's score
|
27
|
-
-- is less than the current pull timestamp, reset
|
28
|
-
-- the inflight score for the the message and resend.
|
29
|
-
if #inflightmessage > 0 then
|
30
|
-
if tonumber(inflightmessage[2]) <= timestamp then
|
31
|
-
redis.call('zadd', inflight, timestamp + wait, inflightmessage[1]);
|
32
|
-
return {queue, inflightmessage[1]}
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
12
|
|
37
13
|
-- Pull a facet from the round-robin list.
|
38
14
|
-- This list guarantees each active facet will have a
|
39
15
|
-- message pulled from the queue every time through..
|
40
16
|
local facet = redis.call('rpop', round_robin);
|
17
|
+
local message = nil
|
41
18
|
|
42
19
|
if facet then
|
43
20
|
-- If we found an active facet, we know the facet
|
@@ -46,7 +23,7 @@ for i, queue in ipairs(ARGV) do
|
|
46
23
|
local messages = k(queue, facet);
|
47
24
|
local inflight_total = k(queue, facet .. ':inflight');
|
48
25
|
|
49
|
-
|
26
|
+
message = redis.call('rpop', messages);
|
50
27
|
|
51
28
|
if message then
|
52
29
|
if wait ~= -1 then
|
@@ -56,44 +33,101 @@ for i, queue in ipairs(ARGV) do
|
|
56
33
|
|
57
34
|
redis.call('decr', k(queue, 'length'));
|
58
35
|
end
|
36
|
+
end
|
59
37
|
|
60
|
-
|
61
|
-
|
62
|
-
local priority = tonumber(redis.call('hget', priorities, facet)) or 1;
|
63
|
-
local length = redis.call('llen', messages);
|
64
|
-
local inflight_cur = tonumber(redis.call('get', inflight_total)) or 0;
|
65
|
-
local inflight_max = tonumber(redis.call('get', inflight_limit)) or 0;
|
38
|
+
return {facet, message};
|
39
|
+
end
|
66
40
|
|
67
|
-
|
41
|
+
local manage = function (queue, facet)
|
42
|
+
local active_facets = k(queue, 'active_facets');
|
43
|
+
local round_robin = k(queue, 'facet_queue');
|
44
|
+
local inflight_limit = k(queue, 'limit');
|
45
|
+
local priorities = k(queue, 'priorities');
|
46
|
+
local facet_pool = k(queue, 'facet_pool');
|
47
|
+
local messages = k(queue, facet);
|
48
|
+
local inflight_total = k(queue, facet .. ':inflight');
|
49
|
+
|
50
|
+
local current = tonumber(redis.call('hget', facet_pool, facet)) or 0;
|
51
|
+
local priority = tonumber(redis.call('hget', priorities, facet)) or 1;
|
52
|
+
local length = redis.call('llen', messages);
|
53
|
+
local inflight_cur = tonumber(redis.call('get', inflight_total)) or 0;
|
54
|
+
local inflight_max = tonumber(redis.call('get', inflight_limit)) or 0;
|
55
|
+
|
56
|
+
local n = 0
|
57
|
+
|
58
|
+
-- redis.log(redis.LOG_WARNING, current.."/"..length.."/"..priority.."/"..inflight_max.."/"..inflight_cur);
|
59
|
+
|
60
|
+
if inflight_max > 0 then
|
61
|
+
n = math.min(length, priority, inflight_max - inflight_cur);
|
62
|
+
else
|
63
|
+
n = math.min(length, priority);
|
64
|
+
end
|
65
|
+
|
66
|
+
-- redis.log(redis.LOG_WARNING, "PULL: "..current.."/"..n);
|
67
|
+
|
68
|
+
if n < current then
|
69
|
+
-- redis.log(redis.LOG_WARNING, "shrinking");
|
70
|
+
redis.call('hset', facet_pool, facet, current - 1);
|
71
|
+
elseif n > current then
|
72
|
+
-- redis.log(redis.LOG_WARNING, "growing");
|
73
|
+
redis.call('lpush', round_robin, facet);
|
74
|
+
redis.call('lpush', round_robin, facet);
|
75
|
+
redis.call('hset', facet_pool, facet, current + 1);
|
76
|
+
else
|
77
|
+
-- redis.log(redis.LOG_WARNING, "maintaining");
|
78
|
+
redis.call('lpush', round_robin, facet);
|
79
|
+
end
|
80
|
+
|
81
|
+
if (length == 0 and inflight_cur == 0 and n == 0) then
|
82
|
+
redis.call('del', inflight_total);
|
83
|
+
redis.call('hdel', facet_pool, facet);
|
84
|
+
redis.call('srem', active_facets, facet);
|
85
|
+
end
|
86
|
+
end
|
68
87
|
|
69
|
-
|
88
|
+
-- Multiple queues can be passed through
|
89
|
+
-- fairway_pull. We'll loop through all
|
90
|
+
-- provided queues, and return a message
|
91
|
+
-- from the first one that isn't empty.
|
92
|
+
for i, queue in ipairs(ARGV) do
|
93
|
+
local inflight = k(queue, 'inflight');
|
70
94
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
end
|
95
|
+
if wait ~= -1 then
|
96
|
+
-- Check if any current inflight messages
|
97
|
+
-- have been inflight for a long time.
|
98
|
+
local inflightmessage = redis.call('zrange', inflight, 0, 0, 'WITHSCORES');
|
76
99
|
|
77
|
-
--
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
redis.call('lpush', round_robin, facet);
|
86
|
-
redis.call('hset', facet_pool, facet, current + 1);
|
87
|
-
else
|
88
|
-
-- redis.log(redis.LOG_WARNING, "maintaining");
|
89
|
-
redis.call('lpush', round_robin, facet);
|
100
|
+
-- If we have an inflight message and it's score
|
101
|
+
-- is less than the current pull timestamp, reset
|
102
|
+
-- the inflight score for the the message and resend.
|
103
|
+
if #inflightmessage > 0 then
|
104
|
+
if tonumber(inflightmessage[2]) <= timestamp then
|
105
|
+
redis.call('zadd', inflight, timestamp + wait, inflightmessage[1]);
|
106
|
+
return {queue, inflightmessage[1]}
|
107
|
+
end
|
90
108
|
end
|
109
|
+
end
|
91
110
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
111
|
+
local pulled = pull(queue);
|
112
|
+
local facet = pulled[1];
|
113
|
+
local message = pulled[2];
|
114
|
+
|
115
|
+
if facet then
|
116
|
+
manage(queue, facet);
|
117
|
+
|
118
|
+
-- if message then
|
119
|
+
-- else
|
120
|
+
-- -- TODO loop through until we find a message
|
121
|
+
-- pulled = pull(queue);
|
122
|
+
-- facet = pulled[1];
|
123
|
+
-- message = pulled[2];
|
124
|
+
|
125
|
+
-- if facet then
|
126
|
+
-- manage(queue, facet);
|
127
|
+
-- end
|
128
|
+
-- end
|
96
129
|
|
97
130
|
return {queue, message};
|
98
131
|
end
|
99
132
|
end
|
133
|
+
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fairway
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Allison
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-02-
|
11
|
+
date: 2016-02-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|