class Redis::Distributed
Attributes
Public Class Methods
# File lib/redis/distributed.rb, line 18 def initialize(node_configs, options = {}) @tag = options[:tag] || /^\{(.+?)\}/ @ring = options[:ring] || HashRing.new @node_configs = node_configs.dup @default_options = options.dup node_configs.each { |node_config| add_node(node_config) } @subscribed_node = nil end
Public Instance Methods
# File lib/redis/distributed.rb, line 341 def [](key) get(key) end
# File lib/redis/distributed.rb, line 345 def []=(key,value) set(key, value) end
# File lib/redis/distributed.rb, line 392 def _bpop(cmd, args) options = {} case args.last when Hash options = args.pop when Integer # Issue deprecation notice in obnoxious mode... options[:timeout] = args.pop end if args.size > 1 # Issue deprecation notice in obnoxious mode... end keys = args.flatten ensure_same_node(cmd, keys) do |node| node.__send__(cmd, keys, options) end end
# File lib/redis/distributed.rb, line 809 def _eval(cmd, args) script = args.shift options = args.pop if args.last.is_a?(Hash) options ||= {} keys = args.shift || options[:keys] || [] argv = args.shift || options[:argv] || [] ensure_same_node(cmd, keys) do |node| node.send(cmd, script, keys, argv) end end
# File lib/redis/distributed.rb, line 35 def add_node(options) options = { :url => options } if options.is_a?(String) options = @default_options.merge(options) @ring.add_node Redis.new( options ) end
Append a value to a key.
# File lib/redis/distributed.rb, line 310 def append(key, value) node_for(key).append(key, value) end
Asynchronously save the dataset to disk.
# File lib/redis/distributed.rb, line 62 def bgsave on_each_node :bgsave end
Count the number of set bits in a range of the string value stored at key.
# File lib/redis/distributed.rb, line 315 def bitcount(key, start = 0, stop = -1) node_for(key).bitcount(key, start, stop) end
Perform a bitwise operation between strings and store the resulting string in a key.
# File lib/redis/distributed.rb, line 320 def bitop(operation, destkey, *keys) ensure_same_node(:bitop, [destkey] + keys) do |node| node.bitop(operation, destkey, *keys) end end
Return the position of the first bit set to 1 or 0 in a string.
# File lib/redis/distributed.rb, line 327 def bitpos(key, bit, start=nil, stop=nil) node_for(key).bitpos(key, bit, start, stop) end
Remove and get the first element in a list, or block until one is available.
# File lib/redis/distributed.rb, line 416 def blpop(*args) _bpop(:blpop, args) end
Remove and get the last element in a list, or block until one is available.
# File lib/redis/distributed.rb, line 422 def brpop(*args) _bpop(:brpop, args) end
Pop a value from a list, push it to another list and return it; or block until one is available.
# File lib/redis/distributed.rb, line 428 def brpoplpush(source, destination, options = {}) case options when Integer # Issue deprecation notice in obnoxious mode... options = { :timeout => options } end ensure_same_node(:brpoplpush, [source, destination]) do |node| node.brpoplpush(source, destination, options) end end
Return the number of keys in the selected database.
# File lib/redis/distributed.rb, line 67 def dbsize on_each_node :dbsize end
Decrement the integer value of a key by one.
# File lib/redis/distributed.rb, line 213 def decr(key) node_for(key).decr(key) end
Decrement the integer value of a key by the given number.
# File lib/redis/distributed.rb, line 218 def decrby(key, decrement) node_for(key).decrby(key, decrement) end
Delete a key.
# File lib/redis/distributed.rb, line 157 def del(*args) keys_per_node = args.group_by { |key| node_for(key) } keys_per_node.inject(0) do |sum, (node, keys)| sum + node.del(*keys) end end
Discard all commands issued after MULTI.
# File lib/redis/distributed.rb, line 780 def discard raise CannotDistribute, :discard end
Return a serialized version of the value stored at a key.
# File lib/redis/distributed.rb, line 142 def dump(key) node_for(key).dump(key) end
# File lib/redis/distributed.rb, line 836 def dup self.class.new(@node_configs, @default_options) end
Echo the given string.
# File lib/redis/distributed.rb, line 52 def echo(value) on_each_node :echo, value end
Evaluate Lua script.
# File lib/redis/distributed.rb, line 823 def eval(*args) _eval(:eval, args) end
Evaluate Lua script by its SHA.
# File lib/redis/distributed.rb, line 828 def evalsha(*args) _eval(:evalsha, args) end
Execute all commands issued after MULTI.
# File lib/redis/distributed.rb, line 775 def exec raise CannotDistribute, :exec end
Determine if a key exists.
# File lib/redis/distributed.rb, line 165 def exists(key) node_for(key).exists(key) end
Set a key's time to live in seconds.
# File lib/redis/distributed.rb, line 112 def expire(key, seconds) node_for(key).expire(key, seconds) end
Set the expiration for a key as a UNIX timestamp.
# File lib/redis/distributed.rb, line 117 def expireat(key, unix_time) node_for(key).expireat(key, unix_time) end
Remove all keys from all databases.
# File lib/redis/distributed.rb, line 72 def flushall on_each_node :flushall end
Remove all keys from the current database.
# File lib/redis/distributed.rb, line 77 def flushdb on_each_node :flushdb end
Get the value of a key.
# File lib/redis/distributed.rb, line 276 def get(key) node_for(key).get(key) end
Returns the bit value at offset in the string value stored at key.
# File lib/redis/distributed.rb, line 305 def getbit(key, offset) node_for(key).getbit(key, offset) end
Get a substring of the string stored at a key.
# File lib/redis/distributed.rb, line 295 def getrange(key, start, stop) node_for(key).getrange(key, start, stop) end
Set the string value of a key and return its old value.
# File lib/redis/distributed.rb, line 332 def getset(key, value) node_for(key).getset(key, value) end
Delete one or more hash fields.
# File lib/redis/distributed.rb, line 682 def hdel(key, field) node_for(key).hdel(key, field) end
Determine if a hash field exists.
# File lib/redis/distributed.rb, line 687 def hexists(key, field) node_for(key).hexists(key, field) end
Get the value of a hash field.
# File lib/redis/distributed.rb, line 668 def hget(key, field) node_for(key).hget(key, field) end
Get all the fields and values in a hash.
# File lib/redis/distributed.rb, line 712 def hgetall(key) node_for(key).hgetall(key) end
Increment the integer value of a hash field by the given integer number.
# File lib/redis/distributed.rb, line 692 def hincrby(key, field, increment) node_for(key).hincrby(key, field, increment) end
Increment the numeric value of a hash field by the given float number.
# File lib/redis/distributed.rb, line 697 def hincrbyfloat(key, field, increment) node_for(key).hincrbyfloat(key, field, increment) end
Get all the fields in a hash.
# File lib/redis/distributed.rb, line 702 def hkeys(key) node_for(key).hkeys(key) end
Get the number of fields in a hash.
# File lib/redis/distributed.rb, line 644 def hlen(key) node_for(key).hlen(key) end
Get the values of all the given hash fields.
# File lib/redis/distributed.rb, line 673 def hmget(key, *fields) node_for(key).hmget(key, *fields) end
Set multiple hash fields to multiple values.
# File lib/redis/distributed.rb, line 659 def hmset(key, *attrs) node_for(key).hmset(key, *attrs) end
Set the string value of a hash field.
# File lib/redis/distributed.rb, line 649 def hset(key, field, value) node_for(key).hset(key, field, value) end
Set the value of a hash field, only if the field does not exist.
# File lib/redis/distributed.rb, line 654 def hsetnx(key, field, value) node_for(key).hsetnx(key, field, value) end
Get all the values in a hash.
# File lib/redis/distributed.rb, line 707 def hvals(key) node_for(key).hvals(key) end
Increment the integer value of a key by one.
# File lib/redis/distributed.rb, line 223 def incr(key) node_for(key).incr(key) end
Increment the integer value of a key by the given integer number.
# File lib/redis/distributed.rb, line 228 def incrby(key, increment) node_for(key).incrby(key, increment) end
Increment the numeric value of a key by the given float number.
# File lib/redis/distributed.rb, line 233 def incrbyfloat(key, increment) node_for(key).incrbyfloat(key, increment) end
Get information and statistics about the server.
# File lib/redis/distributed.rb, line 82 def info(cmd = nil) on_each_node :info, cmd end
# File lib/redis/distributed.rb, line 832 def inspect "#<Redis client v#{Redis::VERSION} for #{nodes.map(&:id).join(', ')}>" end
Find all keys matching the given pattern.
# File lib/redis/distributed.rb, line 170 def keys(glob = "*") on_each_node(:keys, glob).flatten end
Get the UNIX time stamp of the last successful save to disk.
# File lib/redis/distributed.rb, line 87 def lastsave on_each_node :lastsave end
Get an element from a list by its index.
# File lib/redis/distributed.rb, line 441 def lindex(key, index) node_for(key).lindex(key, index) end
Insert an element before or after another element in a list.
# File lib/redis/distributed.rb, line 446 def linsert(key, where, pivot, value) node_for(key).linsert(key, where, pivot, value) end
Get the length of a list.
# File lib/redis/distributed.rb, line 350 def llen(key) node_for(key).llen(key) end
Remove and get the first element in a list.
# File lib/redis/distributed.rb, line 375 def lpop(key) node_for(key).lpop(key) end
Prepend one or more values to a list.
# File lib/redis/distributed.rb, line 355 def lpush(key, value) node_for(key).lpush(key, value) end
Prepend a value to a list, only if the list exists.
# File lib/redis/distributed.rb, line 360 def lpushx(key, value) node_for(key).lpushx(key, value) end
Get a range of elements from a list.
# File lib/redis/distributed.rb, line 451 def lrange(key, start, stop) node_for(key).lrange(key, start, stop) end
Remove elements from a list.
# File lib/redis/distributed.rb, line 456 def lrem(key, count, value) node_for(key).lrem(key, count, value) end
Set the value of an element in a list by its index.
# File lib/redis/distributed.rb, line 461 def lset(key, index, value) node_for(key).lset(key, index, value) end
Trim a list to the specified range.
# File lib/redis/distributed.rb, line 466 def ltrim(key, start, stop) node_for(key).ltrim(key, start, stop) end
# File lib/redis/distributed.rb, line 677 def mapped_hmget(key, *fields) Hash[*fields.zip(hmget(key, *fields)).flatten] end
# File lib/redis/distributed.rb, line 663 def mapped_hmset(key, hash) node_for(key).hmset(key, *hash.to_a.flatten) end
# File lib/redis/distributed.rb, line 285 def mapped_mget(*keys) raise CannotDistribute, :mapped_mget end
# File lib/redis/distributed.rb, line 262 def mapped_mset(hash) raise CannotDistribute, :mapped_mset end
# File lib/redis/distributed.rb, line 271 def mapped_msetnx(hash) raise CannotDistribute, :mapped_msetnx end
Get the values of all the given keys.
# File lib/redis/distributed.rb, line 281 def mget(*keys) raise CannotDistribute, :mget end
Transfer a key from the connected instance to another instance.
# File lib/redis/distributed.rb, line 152 def migrate(key, options) raise CannotDistribute, :migrate end
Listen for all requests received by the server in real time.
# File lib/redis/distributed.rb, line 92 def monitor raise NotImplementedError end
Move a key to another database.
# File lib/redis/distributed.rb, line 175 def move(key, db) node_for(key).move(key, db) end
Set multiple keys to multiple values.
# File lib/redis/distributed.rb, line 258 def mset(*args) raise CannotDistribute, :mset end
Set multiple keys to multiple values, only if none of the keys exist.
# File lib/redis/distributed.rb, line 267 def msetnx(*args) raise CannotDistribute, :msetnx end
Mark the start of a transaction block.
# File lib/redis/distributed.rb, line 770 def multi raise CannotDistribute, :multi end
# File lib/redis/distributed.rb, line 27 def node_for(key) @ring.get_node(key_tag(key.to_s) || key.to_s) end
# File lib/redis/distributed.rb, line 31 def nodes @ring.nodes end
Remove the expiration from a key.
# File lib/redis/distributed.rb, line 107 def persist(key) node_for(key).persist(key) end
Set a key's time to live in milliseconds.
# File lib/redis/distributed.rb, line 127 def pexpire(key, milliseconds) node_for(key).pexpire(key, milliseconds) end
Set the expiration for a key as number of milliseconds from UNIX Epoch.
# File lib/redis/distributed.rb, line 132 def pexpireat(key, ms_unix_time) node_for(key).pexpireat(key, ms_unix_time) end
Add one or more members to a HyperLogLog structure.
# File lib/redis/distributed.rb, line 790 def pfadd(key, member) node_for(key).pfadd(key, member) end
Get the approximate cardinality of members added to HyperLogLog structure.
# File lib/redis/distributed.rb, line 795 def pfcount(*keys) ensure_same_node(:pfcount, keys.flatten(1)) do |node| node.pfcount(keys) end end
Merge multiple HyperLogLog values into an unique value that will approximate the cardinality of the union of the observed Sets of the source HyperLogLog structures.
# File lib/redis/distributed.rb, line 803 def pfmerge(dest_key, *source_key) ensure_same_node(:pfmerge, [dest_key, *source_key]) do |node| node.pfmerge(dest_key, *source_key) end end
Ping the server.
# File lib/redis/distributed.rb, line 47 def ping on_each_node :ping end
# File lib/redis/distributed.rb, line 765 def pipelined raise CannotDistribute, :pipelined end
Set the time to live in milliseconds of a key.
# File lib/redis/distributed.rb, line 248 def psetex(key, ttl, value) node_for(key).psetex(key, ttl, value) end
Listen for messages published to channels matching the given patterns.
# File lib/redis/distributed.rb, line 745 def psubscribe(*channels, &block) raise NotImplementedError end
Get the time to live (in milliseconds) for a key.
# File lib/redis/distributed.rb, line 137 def pttl(key) node_for(key).pttl(key) end
Post a message to a channel.
# File lib/redis/distributed.rb, line 717 def publish(channel, message) node_for(channel).publish(channel, message) end
Stop listening for messages posted to channels matching the given patterns.
# File lib/redis/distributed.rb, line 751 def punsubscribe(*channels) raise NotImplementedError end
Close the connection.
# File lib/redis/distributed.rb, line 57 def quit on_each_node :quit end
Return a random key from the keyspace.
# File lib/redis/distributed.rb, line 180 def randomkey raise CannotDistribute, :randomkey end
Rename a key.
# File lib/redis/distributed.rb, line 185 def rename(old_name, new_name) ensure_same_node(:rename, [old_name, new_name]) do |node| node.rename(old_name, new_name) end end
Rename a key, only if the new key does not exist.
# File lib/redis/distributed.rb, line 192 def renamenx(old_name, new_name) ensure_same_node(:renamenx, [old_name, new_name]) do |node| node.renamenx(old_name, new_name) end end
Create a key using the serialized value, previously obtained using DUMP.
# File lib/redis/distributed.rb, line 147 def restore(key, ttl, serialized_value) node_for(key).restore(key, ttl, serialized_value) end
Remove and get the last element in a list.
# File lib/redis/distributed.rb, line 380 def rpop(key) node_for(key).rpop(key) end
Remove the last element in a list, append it to another list and return it.
# File lib/redis/distributed.rb, line 386 def rpoplpush(source, destination) ensure_same_node(:rpoplpush, [source, destination]) do |node| node.rpoplpush(source, destination) end end
Append one or more values to a list.
# File lib/redis/distributed.rb, line 365 def rpush(key, value) node_for(key).rpush(key, value) end
Append a value to a list, only if the list exists.
# File lib/redis/distributed.rb, line 370 def rpushx(key, value) node_for(key).rpushx(key, value) end
Add one or more members to a set.
# File lib/redis/distributed.rb, line 476 def sadd(key, member) node_for(key).sadd(key, member) end
Synchronously save the dataset to disk.
# File lib/redis/distributed.rb, line 97 def save on_each_node :save end
Get the number of members in a set.
# File lib/redis/distributed.rb, line 471 def scard(key) node_for(key).scard(key) end
Control remote script registry.
# File lib/redis/distributed.rb, line 785 def script(subcommand, *args) on_each_node(:script, subcommand, *args) end
Subtract multiple sets.
# File lib/redis/distributed.rb, line 513 def sdiff(*keys) ensure_same_node(:sdiff, keys) do |node| node.sdiff(*keys) end end
Subtract multiple sets and store the resulting set in a key.
# File lib/redis/distributed.rb, line 520 def sdiffstore(destination, *keys) ensure_same_node(:sdiffstore, [destination] + keys) do |node| node.sdiffstore(destination, *keys) end end
Change the selected database for the current connection.
# File lib/redis/distributed.rb, line 42 def select(db) on_each_node :select, db end
Set the string value of a key.
# File lib/redis/distributed.rb, line 238 def set(key, value, options = {}) node_for(key).set(key, value, options) end
Sets or clears the bit at offset in the string value stored at key.
# File lib/redis/distributed.rb, line 300 def setbit(key, offset, value) node_for(key).setbit(key, offset, value) end
Set the time to live in seconds of a key.
# File lib/redis/distributed.rb, line 243 def setex(key, ttl, value) node_for(key).setex(key, ttl, value) end
Set the value of a key, only if the key does not exist.
# File lib/redis/distributed.rb, line 253 def setnx(key, value) node_for(key).setnx(key, value) end
Overwrite part of a string at key starting at the specified offset.
# File lib/redis/distributed.rb, line 290 def setrange(key, offset, value) node_for(key).setrange(key, offset, value) end
Intersect multiple sets.
# File lib/redis/distributed.rb, line 527 def sinter(*keys) ensure_same_node(:sinter, keys) do |node| node.sinter(*keys) end end
Intersect multiple sets and store the resulting set in a key.
# File lib/redis/distributed.rb, line 534 def sinterstore(destination, *keys) ensure_same_node(:sinterstore, [destination] + keys) do |node| node.sinterstore(destination, *keys) end end
Determine if a given value is a member of a set.
# File lib/redis/distributed.rb, line 503 def sismember(key, member) node_for(key).sismember(key, member) end
Get all the members in a set.
# File lib/redis/distributed.rb, line 508 def smembers(key) node_for(key).smembers(key) end
Move a member from one set to another.
# File lib/redis/distributed.rb, line 496 def smove(source, destination, member) ensure_same_node(:smove, [source, destination]) do |node| node.smove(source, destination, member) end end
Sort the elements in a list, set or sorted set.
# File lib/redis/distributed.rb, line 199 def sort(key, options = {}) keys = [key, options[:by], options[:store], *Array(options[:get])].compact ensure_same_node(:sort, keys) do |node| node.sort(key, options) end end
Remove and return a random member from a set.
# File lib/redis/distributed.rb, line 486 def spop(key) node_for(key).spop(key) end
Get a random member from a set.
# File lib/redis/distributed.rb, line 491 def srandmember(key, count = nil) node_for(key).srandmember(key, count) end
Remove one or more members from a set.
# File lib/redis/distributed.rb, line 481 def srem(key, member) node_for(key).srem(key, member) end
Get the length of the value stored in a key.
# File lib/redis/distributed.rb, line 337 def strlen(key) node_for(key).strlen(key) end
Listen for messages published to the given channels.
# File lib/redis/distributed.rb, line 726 def subscribe(channel, *channels, &block) if channels.empty? @subscribed_node = node_for(channel) @subscribed_node.subscribe(channel, &block) else ensure_same_node(:subscribe, [channel] + channels) do |node| @subscribed_node = node node.subscribe(channel, *channels, &block) end end end
# File lib/redis/distributed.rb, line 721 def subscribed? !! @subscribed_node end
Add multiple sets.
# File lib/redis/distributed.rb, line 541 def sunion(*keys) ensure_same_node(:sunion, keys) do |node| node.sunion(*keys) end end
Add multiple sets and store the resulting set in a key.
# File lib/redis/distributed.rb, line 548 def sunionstore(destination, *keys) ensure_same_node(:sunionstore, [destination] + keys) do |node| node.sunionstore(destination, *keys) end end
Get server time: an UNIX timestamp and the elapsed microseconds in the current second.
# File lib/redis/distributed.rb, line 102 def time on_each_node :time end
Get the time to live (in seconds) for a key.
# File lib/redis/distributed.rb, line 122 def ttl(key) node_for(key).ttl(key) end
Determine the type stored at key.
# File lib/redis/distributed.rb, line 208 def type(key) node_for(key).type(key) end
Stop listening for messages posted to the given channels.
# File lib/redis/distributed.rb, line 739 def unsubscribe(*channels) raise RuntimeError, "Can't unsubscribe if not subscribed." unless subscribed? @subscribed_node.unsubscribe(*channels) end
Forget about all watched keys.
# File lib/redis/distributed.rb, line 761 def unwatch raise CannotDistribute, :unwatch end
Watch the given keys to determine execution of the MULTI/EXEC block.
# File lib/redis/distributed.rb, line 756 def watch(*keys) raise CannotDistribute, :watch end
Add one or more members to a sorted set, or update the score for members that already exist.
# File lib/redis/distributed.rb, line 561 def zadd(key, *args) node_for(key).zadd(key, *args) end
Get the number of members in a sorted set.
# File lib/redis/distributed.rb, line 555 def zcard(key) node_for(key).zcard(key) end
Get the number of members in a particular score range.
# File lib/redis/distributed.rb, line 624 def zcount(key, min, max) node_for(key).zcount(key, min, max) end
Increment the score of a member in a sorted set.
# File lib/redis/distributed.rb, line 566 def zincrby(key, increment, member) node_for(key).zincrby(key, increment, member) end
Intersect multiple sorted sets and store the resulting sorted set in a new key.
# File lib/redis/distributed.rb, line 630 def zinterstore(destination, keys, options = {}) ensure_same_node(:zinterstore, [destination] + keys) do |node| node.zinterstore(destination, keys, options) end end
Return a range of members in a sorted set, by index.
# File lib/redis/distributed.rb, line 581 def zrange(key, start, stop, options = {}) node_for(key).zrange(key, start, stop, options) end
Return a range of members in a sorted set, by score.
# File lib/redis/distributed.rb, line 608 def zrangebyscore(key, min, max, options = {}) node_for(key).zrangebyscore(key, min, max, options) end
Determine the index of a member in a sorted set.
# File lib/redis/distributed.rb, line 592 def zrank(key, member) node_for(key).zrank(key, member) end
Remove one or more members from a sorted set.
# File lib/redis/distributed.rb, line 571 def zrem(key, member) node_for(key).zrem(key, member) end
Remove all members in a sorted set within the given indexes.
# File lib/redis/distributed.rb, line 603 def zremrangebyrank(key, start, stop) node_for(key).zremrangebyrank(key, start, stop) end
Remove all members in a sorted set within the given scores.
# File lib/redis/distributed.rb, line 619 def zremrangebyscore(key, min, max) node_for(key).zremrangebyscore(key, min, max) end
Return a range of members in a sorted set, by index, with scores ordered from high to low.
# File lib/redis/distributed.rb, line 587 def zrevrange(key, start, stop, options = {}) node_for(key).zrevrange(key, start, stop, options) end
Return a range of members in a sorted set, by score, with scores ordered from high to low.
# File lib/redis/distributed.rb, line 614 def zrevrangebyscore(key, max, min, options = {}) node_for(key).zrevrangebyscore(key, max, min, options) end
Determine the index of a member in a sorted set, with scores ordered from high to low.
# File lib/redis/distributed.rb, line 598 def zrevrank(key, member) node_for(key).zrevrank(key, member) end
Get the score associated with the given member in a sorted set.
# File lib/redis/distributed.rb, line 576 def zscore(key, member) node_for(key).zscore(key, member) end
Add multiple sorted sets and store the resulting sorted set in a new key.
# File lib/redis/distributed.rb, line 637 def zunionstore(destination, keys, options = {}) ensure_same_node(:zunionstore, [destination] + keys) do |node| node.zunionstore(destination, keys, options) end end
Protected Instance Methods
# File lib/redis/distributed.rb, line 856 def ensure_same_node(command, keys) all = true tags = keys.map do |key| tag = key_tag(key) all = false unless tag tag end if (all && tags.uniq.size != 1) || (!all && keys.uniq.size != 1) # Not 1 unique tag or not 1 unique key raise CannotDistribute, command end yield(node_for(keys.first)) end
# File lib/redis/distributed.rb, line 852 def key_tag(key) key.to_s[@tag, 1] if @tag end
# File lib/redis/distributed.rb, line 848 def node_index_for(key) nodes.index(node_for(key)) end
# File lib/redis/distributed.rb, line 842 def on_each_node(command, *args) nodes.map do |node| node.send(command, *args) end end