fairway 0.2.5 → 0.2.6
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 +7 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +14 -13
- data/README.markdown +24 -2
- data/fairway.gemspec +1 -0
- data/go/all_specs_test.go +3 -3
- data/go/channeled_connection_test.go +3 -4
- data/go/config.go +6 -3
- data/go/config_test.go +6 -7
- data/go/connection_test.go +8 -9
- data/go/message.go +1 -1
- data/go/queue_test.go +3 -4
- data/go/scripts.go +5 -5
- data/lib/fairway/config.rb +10 -77
- data/lib/fairway/facet.rb +5 -7
- data/lib/fairway/queue.rb +10 -14
- data/lib/fairway/scripts.rb +5 -32
- data/lib/fairway/version.rb +1 -1
- data/spec/lib/fairway/config_spec.rb +2 -53
- metadata +27 -21
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2b3057c6ab8a45805ace676a8d13f8775ca5b42b
|
4
|
+
data.tar.gz: 0520d51ae3dc1aa63557d1aa253d62f1cf03b1e8
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6592bfbf636f74b6f9deb95c508d74464202b70fab905c8c293e393179c3904c88353aaba1b1fd8784c29c7e94abd4fb993f63d3447e4253f8c1cada4404fcbd
|
7
|
+
data.tar.gz: b6d6099a051fdf43df55f8070ccfc8a0203e3463d2bfbb303ebecaf9e62c31a0c46417b7e80bf413e4f77a41fdaeef0442e9722586c8a807473df989ff45e3d7
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,31 +1,30 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
fairway (0.2.
|
4
|
+
fairway (0.2.1)
|
5
5
|
activesupport
|
6
|
+
connection_pool
|
6
7
|
redis
|
7
8
|
redis-namespace (>= 1.3.0)
|
8
9
|
|
9
10
|
GEM
|
10
11
|
remote: http://rubygems.org/
|
11
12
|
specs:
|
12
|
-
activesupport (
|
13
|
-
i18n (
|
14
|
-
|
13
|
+
activesupport (4.0.2)
|
14
|
+
i18n (~> 0.6, >= 0.6.4)
|
15
|
+
minitest (~> 4.2)
|
16
|
+
multi_json (~> 1.3)
|
17
|
+
thread_safe (~> 0.1)
|
18
|
+
tzinfo (~> 0.3.37)
|
19
|
+
atomic (1.1.14)
|
15
20
|
celluloid (0.12.4)
|
16
21
|
facter (>= 1.6.12)
|
17
22
|
timers (>= 1.0.0)
|
18
|
-
columnize (0.3.6)
|
19
23
|
connection_pool (1.0.0)
|
20
|
-
debugger (1.6.0)
|
21
|
-
columnize (>= 0.3.1)
|
22
|
-
debugger-linecache (~> 1.2.0)
|
23
|
-
debugger-ruby_core_source (~> 1.2.1)
|
24
|
-
debugger-linecache (1.2.0)
|
25
|
-
debugger-ruby_core_source (1.2.2)
|
26
24
|
diff-lcs (1.1.3)
|
27
25
|
facter (1.6.17)
|
28
|
-
i18n (0.6.
|
26
|
+
i18n (0.6.9)
|
27
|
+
minitest (4.7.5)
|
29
28
|
multi_json (1.5.0)
|
30
29
|
rake (10.1.0)
|
31
30
|
redis (3.0.4)
|
@@ -45,13 +44,15 @@ GEM
|
|
45
44
|
multi_json (~> 1)
|
46
45
|
redis (~> 3)
|
47
46
|
redis-namespace
|
47
|
+
thread_safe (0.1.3)
|
48
|
+
atomic
|
48
49
|
timers (1.1.0)
|
50
|
+
tzinfo (0.3.38)
|
49
51
|
|
50
52
|
PLATFORMS
|
51
53
|
ruby
|
52
54
|
|
53
55
|
DEPENDENCIES
|
54
|
-
debugger
|
55
56
|
fairway!
|
56
57
|
rake
|
57
58
|
rspec
|
data/README.markdown
CHANGED
@@ -76,7 +76,11 @@ To add messages to your queues, you deliver them:
|
|
76
76
|
|
77
77
|
```ruby
|
78
78
|
connection = Fairway::Connection.new
|
79
|
-
connection.deliver(
|
79
|
+
connection.deliver(
|
80
|
+
type: "invite_friends",
|
81
|
+
user: "bob",
|
82
|
+
friends: ["nancy", "john"]
|
83
|
+
)
|
80
84
|
```
|
81
85
|
|
82
86
|
Now, any registered queues will receive this message, faceted if you've defined
|
@@ -127,13 +131,31 @@ If you'd like to receive messages with channels that match a pattern:
|
|
127
131
|
|
128
132
|
```ruby
|
129
133
|
Fairway.configure do |config|
|
130
|
-
config.register_queue("
|
134
|
+
config.register_queue("all_invites", "invite_.*")
|
131
135
|
end
|
132
136
|
```
|
133
137
|
|
134
138
|
Now, messages from the channels `invite_friends`, `invite_pets`, `invite_parents` will
|
135
139
|
be delivered to the `invite_queue`.
|
136
140
|
|
141
|
+
```ruby
|
142
|
+
conn.deliver(
|
143
|
+
type: "invite_friends",
|
144
|
+
user: "bob",
|
145
|
+
friends: ["nancy", "john"]
|
146
|
+
)
|
147
|
+
conn.deliver(
|
148
|
+
type: "invite_family",
|
149
|
+
user: "bob",
|
150
|
+
family: ["mom", "pop"]
|
151
|
+
)
|
152
|
+
conn.deliver(
|
153
|
+
type: "send_invitation",
|
154
|
+
user: "bob",
|
155
|
+
recipients: ["nancy@example.com", "john@example.com"]
|
156
|
+
)
|
157
|
+
```
|
158
|
+
|
137
159
|
## Subscribing to messages
|
138
160
|
|
139
161
|
To listen for messages without the overhead of queuing them, you can subscribe:
|
data/fairway.gemspec
CHANGED
data/go/all_specs_test.go
CHANGED
@@ -2,7 +2,7 @@ package fairway
|
|
2
2
|
|
3
3
|
import (
|
4
4
|
"github.com/customerio/gospec"
|
5
|
-
"github.com/
|
5
|
+
"github.com/customerio/redigo/redis"
|
6
6
|
"testing"
|
7
7
|
)
|
8
8
|
|
@@ -18,8 +18,8 @@ func TestAllSpecs(t *testing.T) {
|
|
18
18
|
r.Parallel = false
|
19
19
|
|
20
20
|
r.BeforeEach = func() {
|
21
|
-
|
22
|
-
conn
|
21
|
+
conn, _ := redis.Dial("tcp", "localhost:6379")
|
22
|
+
conn.Do("select", 15)
|
23
23
|
conn.Do("flushdb")
|
24
24
|
}
|
25
25
|
|
@@ -4,12 +4,11 @@ import (
|
|
4
4
|
"fmt"
|
5
5
|
"github.com/customerio/gospec"
|
6
6
|
. "github.com/customerio/gospec"
|
7
|
-
"github.com/
|
7
|
+
"github.com/customerio/redigo/redis"
|
8
8
|
)
|
9
9
|
|
10
10
|
func ChanneledConnectionSpec(c gospec.Context) {
|
11
|
-
|
12
|
-
config := NewConfig("localhost:6400", 2)
|
11
|
+
config := NewConfig("localhost:6379", "15", 2)
|
13
12
|
config.AddQueue("myqueue", "typea")
|
14
13
|
config.AddQueue("myqueue2", "typeb")
|
15
14
|
|
@@ -20,7 +19,7 @@ func ChanneledConnectionSpec(c gospec.Context) {
|
|
20
19
|
|
21
20
|
c.Specify("Deliver", func() {
|
22
21
|
c.Specify("only queues up message for matching queues", func() {
|
23
|
-
r := config.
|
22
|
+
r := config.Pool.Get()
|
24
23
|
defer r.Close()
|
25
24
|
|
26
25
|
count, _ := redis.Int(r.Do("llen", "fairway:myqueue:default"))
|
data/go/config.go
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
package fairway
|
2
2
|
|
3
3
|
import (
|
4
|
-
"github.com/
|
4
|
+
"github.com/customerio/redigo/redis"
|
5
5
|
"time"
|
6
6
|
)
|
7
7
|
|
@@ -14,7 +14,7 @@ type Config struct {
|
|
14
14
|
Namespace string
|
15
15
|
Facet func(message *Msg) string
|
16
16
|
queues []*QueueDefinition
|
17
|
-
|
17
|
+
Pool *redis.Pool
|
18
18
|
}
|
19
19
|
|
20
20
|
func (c *Config) AddQueue(name, channel string) {
|
@@ -25,7 +25,7 @@ func (c *Config) scripts() *scripts {
|
|
25
25
|
return newScripts(c)
|
26
26
|
}
|
27
27
|
|
28
|
-
func NewConfig(server string, poolSize int) *Config {
|
28
|
+
func NewConfig(server string, db string, poolSize int) *Config {
|
29
29
|
return &Config{
|
30
30
|
"fairway",
|
31
31
|
func(message *Msg) string { return "default" },
|
@@ -39,6 +39,9 @@ func NewConfig(server string, poolSize int) *Config {
|
|
39
39
|
if err != nil {
|
40
40
|
return nil, err
|
41
41
|
}
|
42
|
+
|
43
|
+
c.Do("select", db)
|
44
|
+
|
42
45
|
return c, err
|
43
46
|
},
|
44
47
|
TestOnBorrow: func(c redis.Conn, t time.Time) error {
|
data/go/config_test.go
CHANGED
@@ -6,8 +6,7 @@ import (
|
|
6
6
|
)
|
7
7
|
|
8
8
|
func ConfigSpec(c gospec.Context) {
|
9
|
-
|
10
|
-
config := NewConfig("localhost:6400", 10)
|
9
|
+
config := NewConfig("localhost:6379", "15", 10)
|
11
10
|
|
12
11
|
c.Specify("NewConfig", func() {
|
13
12
|
c.Specify("namespace is fairway", func() {
|
@@ -25,11 +24,11 @@ func ConfigSpec(c gospec.Context) {
|
|
25
24
|
})
|
26
25
|
|
27
26
|
c.Specify("sets redis pool size", func() {
|
28
|
-
c.Expect(config.
|
29
|
-
c.Expect(config.
|
30
|
-
config = NewConfig("localhost:
|
31
|
-
c.Expect(config.
|
32
|
-
c.Expect(config.
|
27
|
+
c.Expect(config.Pool.MaxIdle, Equals, 10)
|
28
|
+
c.Expect(config.Pool.MaxActive, Equals, 10)
|
29
|
+
config = NewConfig("localhost:6379", "15", 20)
|
30
|
+
c.Expect(config.Pool.MaxIdle, Equals, 20)
|
31
|
+
c.Expect(config.Pool.MaxActive, Equals, 20)
|
33
32
|
})
|
34
33
|
|
35
34
|
c.Specify("can specify custom namespace", func() {
|
data/go/connection_test.go
CHANGED
@@ -3,12 +3,11 @@ package fairway
|
|
3
3
|
import (
|
4
4
|
"github.com/customerio/gospec"
|
5
5
|
. "github.com/customerio/gospec"
|
6
|
-
"github.com/
|
6
|
+
"github.com/customerio/redigo/redis"
|
7
7
|
)
|
8
8
|
|
9
9
|
func ConnectionSpec(c gospec.Context) {
|
10
|
-
|
11
|
-
config := NewConfig("localhost:6400", 2)
|
10
|
+
config := NewConfig("localhost:6379", "15", 2)
|
12
11
|
config.AddQueue("myqueue", ".*")
|
13
12
|
conn := NewConnection(config)
|
14
13
|
|
@@ -21,7 +20,7 @@ func ConnectionSpec(c gospec.Context) {
|
|
21
20
|
})
|
22
21
|
|
23
22
|
c.Specify("stores registered queues in redis", func() {
|
24
|
-
r := config.
|
23
|
+
r := config.Pool.Get()
|
25
24
|
defer r.Close()
|
26
25
|
|
27
26
|
values, _ := redis.Strings(r.Do("hgetall", "fairway:registered_queues"))
|
@@ -42,7 +41,7 @@ func ConnectionSpec(c gospec.Context) {
|
|
42
41
|
|
43
42
|
c.Specify("Deliver", func() {
|
44
43
|
c.Specify("adds message to the facet for the queue", func() {
|
45
|
-
r := config.
|
44
|
+
r := config.Pool.Get()
|
46
45
|
defer r.Close()
|
47
46
|
|
48
47
|
count, _ := redis.Int(r.Do("llen", "fairway:myqueue:default"))
|
@@ -60,7 +59,7 @@ func ConnectionSpec(c gospec.Context) {
|
|
60
59
|
})
|
61
60
|
|
62
61
|
c.Specify("adds facets to the list of active facets", func() {
|
63
|
-
r := config.
|
62
|
+
r := config.Pool.Get()
|
64
63
|
defer r.Close()
|
65
64
|
|
66
65
|
facets, _ := redis.Strings(r.Do("smembers", "fairway:myqueue:active_facets"))
|
@@ -76,7 +75,7 @@ func ConnectionSpec(c gospec.Context) {
|
|
76
75
|
})
|
77
76
|
|
78
77
|
c.Specify("pushes facet onto the facet queue", func() {
|
79
|
-
r := config.
|
78
|
+
r := config.Pool.Get()
|
80
79
|
defer r.Close()
|
81
80
|
|
82
81
|
count, _ := redis.Int(r.Do("llen", "fairway:myqueue:facet_queue"))
|
@@ -94,7 +93,7 @@ func ConnectionSpec(c gospec.Context) {
|
|
94
93
|
})
|
95
94
|
|
96
95
|
c.Specify("doesn't push facet if already active", func() {
|
97
|
-
r := config.
|
96
|
+
r := config.Pool.Get()
|
98
97
|
defer r.Close()
|
99
98
|
|
100
99
|
r.Do("sadd", "fairway:myqueue:active_facets", "default")
|
@@ -114,7 +113,7 @@ func ConnectionSpec(c gospec.Context) {
|
|
114
113
|
})
|
115
114
|
|
116
115
|
c.Specify("returns error if delivery fails", func() {
|
117
|
-
config := NewConfig("localhost:9999", 2)
|
116
|
+
config := NewConfig("localhost:9999", "15", 2)
|
118
117
|
conn := NewConnection(config)
|
119
118
|
|
120
119
|
msg, _ := NewMsg(map[string]string{})
|
data/go/message.go
CHANGED
data/go/queue_test.go
CHANGED
@@ -3,12 +3,11 @@ package fairway
|
|
3
3
|
import (
|
4
4
|
"github.com/customerio/gospec"
|
5
5
|
. "github.com/customerio/gospec"
|
6
|
-
"github.com/
|
6
|
+
"github.com/customerio/redigo/redis"
|
7
7
|
)
|
8
8
|
|
9
9
|
func QueueSpec(c gospec.Context) {
|
10
|
-
|
11
|
-
config := NewConfig("localhost:6400", 2)
|
10
|
+
config := NewConfig("localhost:6379", "15", 2)
|
12
11
|
config.AddQueue("myqueue", ".*")
|
13
12
|
conn := NewConnection(config)
|
14
13
|
queue := NewQueue(conn, "myqueue")
|
@@ -56,7 +55,7 @@ func QueueSpec(c gospec.Context) {
|
|
56
55
|
})
|
57
56
|
|
58
57
|
c.Specify("removes facet from active list if it becomes empty", func() {
|
59
|
-
r := config.
|
58
|
+
r := config.Pool.Get()
|
60
59
|
defer r.Close()
|
61
60
|
|
62
61
|
msg, _ := NewMsg(map[string]string{})
|
data/go/scripts.go
CHANGED
@@ -2,7 +2,7 @@ package fairway
|
|
2
2
|
|
3
3
|
import (
|
4
4
|
"fmt"
|
5
|
-
"github.com/
|
5
|
+
"github.com/customerio/redigo/redis"
|
6
6
|
)
|
7
7
|
|
8
8
|
type scripts struct {
|
@@ -29,7 +29,7 @@ func (s *scripts) registeredQueuesKey() string {
|
|
29
29
|
}
|
30
30
|
|
31
31
|
func (s *scripts) registerQueue(queue *QueueDefinition) {
|
32
|
-
conn := s.config.
|
32
|
+
conn := s.config.Pool.Get()
|
33
33
|
defer conn.Close()
|
34
34
|
|
35
35
|
_, err := redis.Bool(conn.Do("hset", s.registeredQueuesKey(), queue.name, queue.channel))
|
@@ -40,13 +40,13 @@ func (s *scripts) registerQueue(queue *QueueDefinition) {
|
|
40
40
|
}
|
41
41
|
|
42
42
|
func (s *scripts) registeredQueues() ([]string, error) {
|
43
|
-
conn := s.config.
|
43
|
+
conn := s.config.Pool.Get()
|
44
44
|
defer conn.Close()
|
45
45
|
return redis.Strings(conn.Do("hkeys", s.registeredQueuesKey()))
|
46
46
|
}
|
47
47
|
|
48
48
|
func (s *scripts) deliver(channel, facet string, msg *Msg) error {
|
49
|
-
conn := s.config.
|
49
|
+
conn := s.config.Pool.Get()
|
50
50
|
defer conn.Close()
|
51
51
|
|
52
52
|
script := s.findScript(FairwayDeliver, 1)
|
@@ -57,7 +57,7 @@ func (s *scripts) deliver(channel, facet string, msg *Msg) error {
|
|
57
57
|
}
|
58
58
|
|
59
59
|
func (s *scripts) pull(queueName string) (string, *Msg) {
|
60
|
-
conn := s.config.
|
60
|
+
conn := s.config.Pool.Get()
|
61
61
|
defer conn.Close()
|
62
62
|
|
63
63
|
script := s.findScript(FairwayPull, 1)
|
data/lib/fairway/config.rb
CHANGED
@@ -1,60 +1,15 @@
|
|
1
1
|
module Fairway
|
2
|
-
class RandomDistribution
|
3
|
-
class CannotConnect < RuntimeError; end
|
4
|
-
|
5
|
-
EXCEPTIONS = [
|
6
|
-
Redis::CannotConnectError,
|
7
|
-
Errno::ETIMEDOUT,
|
8
|
-
Errno::EHOSTUNREACH
|
9
|
-
]
|
10
|
-
|
11
|
-
attr_reader :pools
|
12
|
-
|
13
|
-
def initialize(pools)
|
14
|
-
@pools = pools
|
15
|
-
end
|
16
|
-
|
17
|
-
def with(&block)
|
18
|
-
valid_pools = @pools
|
19
|
-
|
20
|
-
while valid_pools.any?
|
21
|
-
pool = valid_pools.sample
|
22
|
-
|
23
|
-
pool.with do |conn|
|
24
|
-
begin
|
25
|
-
return yield(conn)
|
26
|
-
rescue *EXCEPTIONS
|
27
|
-
valid_pools -= [pool]
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
raise CannotConnect.new
|
33
|
-
end
|
34
|
-
|
35
|
-
def with_each(&block)
|
36
|
-
@pools.shuffle.each do |pool|
|
37
|
-
pool.with do |conn|
|
38
|
-
begin
|
39
|
-
yield(conn)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
2
|
class Config
|
47
3
|
attr_accessor :namespace
|
48
|
-
attr_reader :defined_queues, :redis_options
|
4
|
+
attr_reader :defined_queues, :redis_options
|
49
5
|
|
50
6
|
DEFAULT_FACET = "default"
|
51
7
|
|
52
8
|
QueueDefinition = Struct.new(:name, :channel)
|
53
9
|
|
54
10
|
def initialize
|
55
|
-
@redis_options =
|
11
|
+
@redis_options = {}
|
56
12
|
@namespace = nil
|
57
|
-
@distribute = RandomDistribution
|
58
13
|
@facet = lambda { |message| DEFAULT_FACET }
|
59
14
|
@defined_queues = []
|
60
15
|
|
@@ -74,54 +29,32 @@ module Fairway
|
|
74
29
|
end
|
75
30
|
|
76
31
|
def redis=(options)
|
77
|
-
@redis_options =
|
32
|
+
@redis_options = options
|
78
33
|
end
|
79
34
|
|
80
35
|
def redis
|
81
|
-
@redis ||=
|
36
|
+
@redis ||= pool { Redis::Namespace.new(@namespace, redis: raw_redis) }
|
82
37
|
end
|
83
38
|
|
84
39
|
def scripts
|
85
40
|
@scripts ||= begin
|
86
|
-
Scripts.new(
|
41
|
+
Scripts.new(pool { raw_redis }, @namespace)
|
87
42
|
end
|
88
43
|
end
|
89
44
|
|
90
45
|
private
|
91
46
|
|
92
|
-
def
|
93
|
-
@
|
94
|
-
|
95
|
-
pools = @redis_options.map do |options|
|
96
|
-
pool(options) { Redis::Namespace.new(@namespace, redis: raw_redis(options)) }
|
97
|
-
end
|
98
|
-
|
99
|
-
@distribute.new(pools)
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
def raw_redises
|
104
|
-
@raw_redises ||= begin
|
105
|
-
@redis_options << {} if @redis_options.empty?
|
106
|
-
pools = @redis_options.map do |options|
|
107
|
-
pool(options) { raw_redis(options) }
|
108
|
-
end
|
109
|
-
|
110
|
-
@distribute.new(pools)
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
def pool(options, &block)
|
115
|
-
pool_size = options[:pool] || 1
|
116
|
-
pool_timeout = options[:timeout] || 5
|
47
|
+
def pool(&block)
|
48
|
+
pool_size = @redis_options[:pool] || 1
|
49
|
+
pool_timeout = @redis_options[:timeout] || 5
|
117
50
|
|
118
51
|
ConnectionPool.new(size: pool_size, timeout: pool_timeout) do
|
119
52
|
yield
|
120
53
|
end
|
121
54
|
end
|
122
55
|
|
123
|
-
def raw_redis
|
124
|
-
Redis.new(
|
56
|
+
def raw_redis
|
57
|
+
Redis.new(@redis_options)
|
125
58
|
end
|
126
59
|
end
|
127
60
|
end
|
data/lib/fairway/facet.rb
CHANGED
@@ -10,13 +10,11 @@ module Fairway
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def length
|
13
|
-
redis.
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
end
|
19
|
-
end.sum
|
13
|
+
redis.with do |conn|
|
14
|
+
each_queue do |queue|
|
15
|
+
conn.llen(facet_key(queue))
|
16
|
+
end.sum
|
17
|
+
end
|
20
18
|
end
|
21
19
|
|
22
20
|
def priority
|
data/lib/fairway/queue.rb
CHANGED
@@ -8,25 +8,21 @@ module Fairway
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def active_facets
|
11
|
-
|
12
|
-
|
13
|
-
redis.with_each do |conn|
|
14
|
-
facet_names += unique_queues.map do |queue|
|
11
|
+
redis.with do |conn|
|
12
|
+
facet_names = unique_queues.map do |queue|
|
15
13
|
conn.smembers("#{queue}:active_facets")
|
16
|
-
end.flatten
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
14
|
+
end.flatten.uniq
|
15
|
+
|
16
|
+
facet_names.map do |name|
|
17
|
+
Facet.new(self, name)
|
18
|
+
end
|
21
19
|
end
|
22
20
|
end
|
23
21
|
|
24
22
|
def length
|
25
|
-
redis.
|
26
|
-
|
27
|
-
|
28
|
-
end
|
29
|
-
end.sum
|
23
|
+
redis.with do |conn|
|
24
|
+
conn.mget(unique_queues.map{|q| "#{q}:length" }).map(&:to_i).sum
|
25
|
+
end
|
30
26
|
end
|
31
27
|
|
32
28
|
def peek
|
data/lib/fairway/scripts.rb
CHANGED
@@ -15,13 +15,13 @@ module Fairway
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def register_queue(name, channel)
|
18
|
-
redis.
|
18
|
+
redis.with do |conn|
|
19
19
|
conn.hset(registered_queues_key, name, channel)
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
23
|
def unregister_queue(name)
|
24
|
-
redis.
|
24
|
+
redis.with do |conn|
|
25
25
|
conn.hdel(registered_queues_key, name)
|
26
26
|
end
|
27
27
|
end
|
@@ -35,22 +35,12 @@ module Fairway
|
|
35
35
|
def method_missing(method_name, *args)
|
36
36
|
loaded = false
|
37
37
|
|
38
|
-
|
39
|
-
|
40
|
-
conn.evalsha(script_sha(method_name), [namespace], args)
|
41
|
-
end
|
42
|
-
elsif first?(method_name)
|
43
|
-
first_pool do |conn|
|
44
|
-
conn.evalsha(script_sha(method_name), [namespace], args)
|
45
|
-
end
|
46
|
-
else
|
47
|
-
redis.with do |conn|
|
48
|
-
conn.evalsha(script_sha(method_name), [namespace], args)
|
49
|
-
end
|
38
|
+
redis.with do |conn|
|
39
|
+
conn.evalsha(script_sha(method_name), [namespace], args)
|
50
40
|
end
|
51
41
|
rescue Redis::CommandError => ex
|
52
42
|
if ex.message.include?("NOSCRIPT") && !loaded
|
53
|
-
redis.
|
43
|
+
redis.with do |conn|
|
54
44
|
conn.script(:load, script_source(method_name))
|
55
45
|
end
|
56
46
|
|
@@ -63,23 +53,6 @@ module Fairway
|
|
63
53
|
|
64
54
|
private
|
65
55
|
|
66
|
-
def first?(script)
|
67
|
-
["fairway_pull", "fairway_peek"].include?(script.to_s)
|
68
|
-
end
|
69
|
-
|
70
|
-
def multi?(script)
|
71
|
-
["fairway_priority", "fairway_destroy"].include?(script.to_s)
|
72
|
-
end
|
73
|
-
|
74
|
-
def first_pool(&block)
|
75
|
-
redis.with_each do |conn|
|
76
|
-
val = yield(conn)
|
77
|
-
return val if val
|
78
|
-
end
|
79
|
-
|
80
|
-
nil
|
81
|
-
end
|
82
|
-
|
83
56
|
def registered_queues_key
|
84
57
|
"#{namespace}registered_queues"
|
85
58
|
end
|
data/lib/fairway/version.rb
CHANGED
@@ -29,70 +29,19 @@ module Fairway
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
-
it "allows multiple redis config" do
|
33
|
-
config = Config.new do |config|
|
34
|
-
config.redis = [
|
35
|
-
{ host: "127.0.0.1", port: 6379 },
|
36
|
-
{ host: "127.0.0.1", port: 6380 }
|
37
|
-
]
|
38
|
-
end
|
39
|
-
|
40
|
-
config.redis.pools.length.should == 2
|
41
|
-
end
|
42
|
-
|
43
|
-
it "distributes requests randomly between multiple redis's" do
|
44
|
-
config = Config.new do |config|
|
45
|
-
config.redis = [
|
46
|
-
{ host: "127.0.0.1", port: 6379 },
|
47
|
-
{ host: "127.0.0.1", port: 6380 }
|
48
|
-
]
|
49
|
-
end
|
50
|
-
|
51
|
-
ports = []
|
52
|
-
|
53
|
-
20.times do
|
54
|
-
config.redis.with do |conn|
|
55
|
-
ports << conn.info["tcp_port"]
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
ports.uniq.sort.should == ["6379", "6380"]
|
60
|
-
end
|
61
|
-
|
62
|
-
it "doesn't lose requests if one redis is down" do
|
63
|
-
config = Config.new do |config|
|
64
|
-
config.redis = [
|
65
|
-
{ host: "127.0.0.1", port: 6379 },
|
66
|
-
{ host: "127.0.0.1", port: 6380 },
|
67
|
-
{ host: "127.0.0.1", port: 9999 }
|
68
|
-
]
|
69
|
-
end
|
70
|
-
|
71
|
-
ports = []
|
72
|
-
|
73
|
-
20.times do
|
74
|
-
config.redis.with do |conn|
|
75
|
-
ports << conn.info["tcp_port"]
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
ports.length.should == 20
|
80
|
-
ports.uniq.sort.should == ["6379", "6380"]
|
81
|
-
end
|
82
|
-
|
83
32
|
it "allows setting of connection pooling" do
|
84
33
|
config = Config.new do |config|
|
85
34
|
config.redis = { pool: 10 }
|
86
35
|
end
|
87
36
|
|
88
|
-
config.redis.
|
37
|
+
config.redis.instance_variable_get("@size").should == 10
|
89
38
|
end
|
90
39
|
|
91
40
|
it "defaults to pool of 1" do
|
92
41
|
config = Config.new do |config|
|
93
42
|
end
|
94
43
|
|
95
|
-
config.redis.
|
44
|
+
config.redis.instance_variable_get("@size").should == 1
|
96
45
|
end
|
97
46
|
|
98
47
|
it "allows setting of redis namespace" do
|
metadata
CHANGED
@@ -1,64 +1,71 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fairway
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
5
|
-
prerelease:
|
4
|
+
version: 0.2.6
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- John Allison
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2014-01-14 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: activesupport
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - '>='
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: '0'
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- -
|
24
|
+
- - '>='
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: '0'
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: redis
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- -
|
31
|
+
- - '>='
|
36
32
|
- !ruby/object:Gem::Version
|
37
33
|
version: '0'
|
38
34
|
type: :runtime
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- -
|
38
|
+
- - '>='
|
44
39
|
- !ruby/object:Gem::Version
|
45
40
|
version: '0'
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: redis-namespace
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
|
-
- -
|
45
|
+
- - '>='
|
52
46
|
- !ruby/object:Gem::Version
|
53
47
|
version: 1.3.0
|
54
48
|
type: :runtime
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
|
-
- -
|
52
|
+
- - '>='
|
60
53
|
- !ruby/object:Gem::Version
|
61
54
|
version: 1.3.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: connection_pool
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
62
69
|
description: A fair way to queue work in multi-user systems.
|
63
70
|
email:
|
64
71
|
- john@customer.io
|
@@ -121,27 +128,26 @@ files:
|
|
121
128
|
- spec/spec_helper.rb
|
122
129
|
homepage: https://github.com/customerio/fairway
|
123
130
|
licenses: []
|
131
|
+
metadata: {}
|
124
132
|
post_install_message:
|
125
133
|
rdoc_options: []
|
126
134
|
require_paths:
|
127
135
|
- lib
|
128
136
|
required_ruby_version: !ruby/object:Gem::Requirement
|
129
|
-
none: false
|
130
137
|
requirements:
|
131
|
-
- -
|
138
|
+
- - '>='
|
132
139
|
- !ruby/object:Gem::Version
|
133
140
|
version: '0'
|
134
141
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
135
|
-
none: false
|
136
142
|
requirements:
|
137
|
-
- -
|
143
|
+
- - '>='
|
138
144
|
- !ruby/object:Gem::Version
|
139
145
|
version: '0'
|
140
146
|
requirements: []
|
141
147
|
rubyforge_project:
|
142
|
-
rubygems_version:
|
148
|
+
rubygems_version: 2.0.3
|
143
149
|
signing_key:
|
144
|
-
specification_version:
|
150
|
+
specification_version: 4
|
145
151
|
summary: A fair way to queue work in multi-user systems.
|
146
152
|
test_files:
|
147
153
|
- spec/lib/fairway/channeled_connection_spec.rb
|