Class: RedCluster
- Inherits:
-
Object
show all
- Defined in:
- lib/red_cluster.rb,
lib/replica_set.rb,
lib/replica_set.rb
Defined Under Namespace
Classes: NoMaster, ReplicaSet
Constant Summary
collapse
- SINGLE_KEY_KEY_OPS =
%W{del exists expire expireat move persists ttl type}.map(&:to_sym)
- STRING_OPS =
%W{append decr decrby get getbit getrange getset incr incrby mget mset msetnx set setbit setex setnx setrange strlen}.map(&:to_sym)
- HASH_OPS =
%W{hdel hexists hget hgetall hincrby hkeys hlen hmget hmset hset hsetnx hvals}.map(&:to_sym)
- SINGLE_KEY_LIST_OPS =
%W{blpop brpop lindex linsert llen lpop lpush lpushx lrange lrem lset ltrim rpop rpush rpushx}.map(&:to_sym)
- SINGLE_KEY_SET_OPS =
%W{sadd scard sismember smembers spop srandmember srem}.map(&:to_sym)
- SINGLE_KEY_SORTED_SET_OPS =
%W{zadd zcard zcount zincrby zrange zrangebyscore zrank zrem zremrangebyrank zremrangebyscore zrevrange zrevrangebyscore zrevrank zscore}.map(&:to_sym)
- SINGLE_KEY_OPS =
SINGLE_KEY_KEY_OPS + STRING_OPS + HASH_OPS + SINGLE_KEY_LIST_OPS + SINGLE_KEY_SET_OPS + SINGLE_KEY_SORTED_SET_OPS
Instance Attribute Summary collapse
Instance Method Summary
collapse
-
#bgsave ⇒ Object
-
#brpoplpush(src_list, target_list, timeout) ⇒ Object
-
#config(cmd, *args) ⇒ Object
-
#echo(msg) ⇒ Object
-
#exec ⇒ Object
-
#initialize(replica_sets = []) ⇒ RedCluster
constructor
A new instance of RedCluster.
-
#keys(pattern) ⇒ Object
-
#lastsave ⇒ Object
-
#load_aof_file(file_path) ⇒ Object
-
#method_missing(method, *args) ⇒ Object
-
#ping ⇒ Object
-
#randomkey ⇒ Object
-
#rename(key, new_key) ⇒ Object
-
#rpoplpush(src_list, target_list) ⇒ Object
-
#sdiff(*sets) ⇒ Object
-
#sdiffstore(destination, *sets) ⇒ Object
-
#select(db) ⇒ Object
-
#sinter(*sets) ⇒ Object
-
#sinterstore(destination, *sets) ⇒ Object
-
#smove(src, destination, member) ⇒ Object
-
#sunion(*sets) ⇒ Object
-
#sunionstore(destination, *sets) ⇒ Object
-
#zinterstore(destination, input_sets, options = {}) ⇒ Object
-
#zunionstore(destination, input_sets, options = {}) ⇒ Object
Constructor Details
#initialize(replica_sets = []) ⇒ RedCluster
Returns a new instance of RedCluster.
9
10
11
|
# File 'lib/red_cluster.rb', line 9
def initialize(replica_sets = [])
@replica_sets = replica_sets.map { |replica_set| ReplicaSet.new(self, replica_set) }
end
|
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *args) ⇒ Object
133
134
135
136
137
138
139
140
141
|
# File 'lib/red_cluster.rb', line 133
def method_missing(method, *args)
if SINGLE_KEY_OPS.include?(method.to_sym)
key = args.first
replica_set = replica_set_for_key key
replica_set.send method, *args
else
raise "Unsupported operation: #{method}"
end
end
|
Instance Attribute Details
#replica_sets ⇒ Object
Returns the value of attribute replica_sets.
7
8
9
|
# File 'lib/red_cluster.rb', line 7
def replica_sets
@replica_sets
end
|
Instance Method Details
#bgsave ⇒ Object
31
|
# File 'lib/red_cluster.rb', line 31
def bgsave; @replica_sets.each(&:bgsave); "Background saving started"; end
|
#brpoplpush(src_list, target_list, timeout) ⇒ Object
81
82
83
84
85
86
|
# File 'lib/red_cluster.rb', line 81
def brpoplpush(src_list, target_list, timeout)
val = brpop src_list, timeout
return unless val
lpush target_list, val
val
end
|
#config(cmd, *args) ⇒ Object
37
38
39
40
41
42
43
44
|
# File 'lib/red_cluster.rb', line 37
def config(cmd, *args)
if cmd == :get
@replica_sets.inject({}) { |result, replica_set| result.merge(replica_set.config(:get, *args)) }
else
@replica_sets.each { |replica_set| replica_set.config(cmd, *args) }
"OK"
end
end
|
#echo(msg) ⇒ Object
32
|
# File 'lib/red_cluster.rb', line 32
def echo(msg); @replica_sets.each {|replica_set| replica_set.echo(msg) }; msg; end
|
#exec ⇒ Object
47
48
49
50
51
52
53
54
55
|
# File 'lib/red_cluster.rb', line 47
def exec
@multi_count = nil
exec_results = @replica_sets.map(&:exec)
Hash[*exec_results.flatten].sort.map(&:last)
end
|
#keys(pattern) ⇒ Object
34
|
# File 'lib/red_cluster.rb', line 34
def keys(pattern); @replica_sets.map { |replica_set| replica_set.keys pattern }.flatten; end
|
#lastsave ⇒ Object
35
|
# File 'lib/red_cluster.rb', line 35
def lastsave; @replica_sets.map(&:lastsave).min; end
|
#load_aof_file(file_path) ⇒ Object
143
144
145
146
147
148
149
150
151
152
153
154
155
|
# File 'lib/red_cluster.rb', line 143
def load_aof_file(file_path)
aof_file = File.read file_path
commands = aof_file.split /^\*/
commands.each do |cmd|
split_cmd = cmd.split("\r\n")[1..-1]
next unless split_cmd
split_cmd.reject! { |cmd| cmd =~ /^\$/ }
redis_cmd, redis_key, redis_args = split_cmd[0], split_cmd[1], split_cmd[2..-1]
crc32_of_key = Zlib.crc32(redis_key).abs
replica_set = @replica_sets[crc32_of_key % @replica_sets.size]
replica_set.master.send redis_cmd, redis_key, *redis_args
end
end
|
#ping ⇒ Object
30
|
# File 'lib/red_cluster.rb', line 30
def ping; @replica_sets.each(&:ping); "PONG"; end
|
#randomkey ⇒ Object
58
59
60
61
62
63
|
# File 'lib/red_cluster.rb', line 58
def randomkey
replica_sets_with_keys_in_them = @replica_sets.select { |replica_set| replica_set.randomkey != nil }
idx = (rand * replica_sets_with_keys_in_them.count).to_i
rand_replica_set = replica_sets_with_keys_in_them[idx]
rand_replica_set && rand_replica_set.randomkey
end
|
#rename(key, new_key) ⇒ Object
65
66
67
68
69
70
71
|
# File 'lib/red_cluster.rb', line 65
def rename(key, new_key)
raise RuntimeError, "ERR source and destination objects are the same" if key == new_key
raise RuntimeError, "ERR no such key" unless exists(key)
val = get key
del key
set new_key, val
end
|
#rpoplpush(src_list, target_list) ⇒ Object
74
75
76
77
78
79
|
# File 'lib/red_cluster.rb', line 74
def rpoplpush(src_list, target_list)
val = rpop src_list
return unless val
lpush target_list, val
val
end
|
#sdiff(*sets) ⇒ Object
99
100
101
|
# File 'lib/red_cluster.rb', line 99
def sdiff(*sets)
perform_set_strategy :difference, *sets
end
|
#sdiffstore(destination, *sets) ⇒ Object
119
120
121
|
# File 'lib/red_cluster.rb', line 119
def sdiffstore(destination, *sets)
perform_store_strategy :sdiff, destination, *sets
end
|
#select(db) ⇒ Object
22
|
# File 'lib/red_cluster.rb', line 22
def select(db); @replica_sets.each {|replica_set| replica_set.select(db) }; "OK"; end
|
#sinter(*sets) ⇒ Object
103
104
105
|
# File 'lib/red_cluster.rb', line 103
def sinter(*sets)
perform_set_strategy :intersection, *sets
end
|
#sinterstore(destination, *sets) ⇒ Object
111
112
113
|
# File 'lib/red_cluster.rb', line 111
def sinterstore(destination, *sets)
perform_store_strategy :sinter, destination, *sets
end
|
#smove(src, destination, member) ⇒ Object
89
90
91
92
93
94
95
96
97
|
# File 'lib/red_cluster.rb', line 89
def smove(src, destination, member)
if sismember src, member
sadd destination, member
srem src, member
true
else
false
end
end
|
#sunion(*sets) ⇒ Object
107
108
109
|
# File 'lib/red_cluster.rb', line 107
def sunion(*sets)
perform_set_strategy :union, *sets
end
|
#sunionstore(destination, *sets) ⇒ Object
115
116
117
|
# File 'lib/red_cluster.rb', line 115
def sunionstore(destination, *sets)
perform_store_strategy :sunion, destination, *sets
end
|
#zinterstore(destination, input_sets, options = {}) ⇒ Object
124
125
126
|
# File 'lib/red_cluster.rb', line 124
def zinterstore(destination, input_sets, options = {})
perform_sorted_set_store_strategy :intersection, destination, input_sets, options
end
|
#zunionstore(destination, input_sets, options = {}) ⇒ Object
128
129
130
|
# File 'lib/red_cluster.rb', line 128
def zunionstore(destination, input_sets, options = {})
perform_sorted_set_store_strategy :union, destination, input_sets, options
end
|