require 'hash_ring'
class DistRedis
attr_reader :ring
- def initialize(*servers)
- srvs = []
- servers.each do |s|
- server, port = s.split(':')
- srvs << Redis.new(:host => server, :port => port)
+ def initialize(opts={})
+ hosts = []
+
+ db = opts[:db] || nil
+ timeout = opts[:timeout] || nil
+
+ raise Error, "No hosts given" unless opts[:hosts]
+
+ opts[:hosts].each do |h|
+ host, port = h.split(':')
+ hosts << Redis.new(:host => host, :port => port, :db => db, :timeout => timeout)
end
- @ring = HashRing.new srvs
+
+ @ring = HashRing.new hosts
end
-
+
def node_for_key(key)
- if key =~ /\{(.*)?\}/
- key = $1
- end
+ key = $1 if key =~ /\{(.*)?\}/
@ring.get_node(key)
end
-
+
def add_server(server)
server, port = server.split(':')
@ring.add_node Redis.new(:host => server, :port => port)
end
-
+
def method_missing(sym, *args, &blk)
- if redis = node_for_key(args.first)
+ if redis = node_for_key(args.first.to_s)
redis.send sym, *args, &blk
else
super
end
end
-
+
def keys(glob)
- keyz = []
- @ring.nodes.each do |red|
- keyz.concat red.keys(glob)
+ @ring.nodes.map do |red|
+ red.keys(glob)
end
- keyz
end
-
+
def save
- @ring.nodes.each do |red|
- red.save
- end
+ on_each_node :save
end
-
+
def bgsave
- @ring.nodes.each do |red|
- red.bgsave
- end
+ on_each_node :bgsave
end
-
+
def quit
- @ring.nodes.each do |red|
- red.quit
- end
+ on_each_node :quit
+ end
+
+ def flush_all
+ on_each_node :flush_all
end
-
+ alias_method :flushall, :flush_all
+
+ def flush_db
+ on_each_node :flush_db
+ end
+ alias_method :flushdb, :flush_db
+
def delete_cloud!
@ring.nodes.each do |red|
red.keys("*").each do |key|
red.delete key
- end
+ end
+ end
+ end
+
+ def on_each_node(command, *args)
+ @ring.nodes.each do |red|
+ red.send(command, *args)
end
end
-
+
end
p r['urdad2']
p r['urmom3']
p r['urdad3']
-
+
r.push_tail 'listor', 'foo1'
r.push_tail 'listor', 'foo2'
r.push_tail 'listor', 'foo3'
r.push_tail 'listor', 'foo4'
r.push_tail 'listor', 'foo5'
-
- p r.pop_tail 'listor'
- p r.pop_tail 'listor'
- p r.pop_tail 'listor'
- p r.pop_tail 'listor'
- p r.pop_tail 'listor'
-
+
+ p r.pop_tail('listor')
+ p r.pop_tail('listor')
+ p r.pop_tail('listor')
+ p r.pop_tail('listor')
+ p r.pop_tail('listor')
+
puts "key distribution:"
-
+
r.ring.nodes.each do |red|
p [red.port, red.keys("*")]
end