class Ruster::Node

Constants

DB0

In Redis Cluster only DB 0 is enabled

Attributes

addr[R]
config_epoch[R]
flags[R]
friends[R]
id[R]
importing[R]
master_id[R]
migrating[R]
ping_epoch[R]
pong_epoch[R]
slots[R]
state[R]

Public Class Methods

from_info_line(info_line) click to toggle source
# File lib/ruster/node.rb, line 72
def self.from_info_line(info_line)
  _, addr, _ = info_line.split
  new(addr).tap { |node| node.read_info_line!(info_line) }
end
new(addr) click to toggle source
# File lib/ruster/node.rb, line 17
def initialize(addr)
  @addr = addr
end

Public Instance Methods

add_slots(*slots) click to toggle source
# File lib/ruster/node.rb, line 108
def add_slots(*slots)
  call("CLUSTER", "ADDSLOTS", *slots)
end
all_slots() click to toggle source
# File lib/ruster/node.rb, line 64
def all_slots
  slots.map(&:to_a).flatten
end
call(*args) click to toggle source
# File lib/ruster/node.rb, line 25
def call(*args)
  res = client.call(*args)
  raise res if res.is_a?(RuntimeError)
  res
end
client() click to toggle source
# File lib/ruster/node.rb, line 21
def client
  @client ||= Redic.new("redis://#{addr}")
end
cluster_info() click to toggle source
# File lib/ruster/node.rb, line 120
def cluster_info
  parse_info(call("CLUSTER", "INFO"))
end
del_slots(*slots) click to toggle source
# File lib/ruster/node.rb, line 112
def del_slots(*slots)
  call("CLUSTER", "DELSLOTS", *slots)
end
empty?() click to toggle source
# File lib/ruster/node.rb, line 165
def empty?
  call("DBSIZE") == 0
end
enabled?() click to toggle source
# File lib/ruster/node.rb, line 31
def enabled?
  parse_info(call("INFO", "cluster"))[:cluster_enabled] == "1"
end
flush_slots!() click to toggle source
# File lib/ruster/node.rb, line 116
def flush_slots!
  call("CLUSTER", "FLUSHSLOTS")
end
forget(node) click to toggle source
# File lib/ruster/node.rb, line 93
def forget(node)
  raise ArgumentError, "Node #{node} is not empty" unless node.slots.empty? and node.migrating.empty? and node.importing.empty?
  call("CLUSTER", "FORGET", node.id)
end
ip() click to toggle source
# File lib/ruster/node.rb, line 124
def ip
  addr.split(":").first
end
load!() click to toggle source
# File lib/ruster/node.rb, line 77
def load!
  @friends = []

  call("CLUSTER", "NODES").split("\n").each do |line|
    if line.include?("myself")
      read_info_line!(line)
    else
      @friends << self.class.from_info_line(line)
    end
  end
end
meet(ip, port) click to toggle source
# File lib/ruster/node.rb, line 89
def meet(ip, port)
  call("CLUSTER", "MEET", ip, port)
end
move_slot!(slot, target, options={}) click to toggle source
# File lib/ruster/node.rb, line 135
def move_slot!(slot, target, options={})
  options[:num_keys] ||= 10
  options[:timeout]  ||= call("CONFIG", "GET", "cluster-node-timeout")

  # Tell the target node to import the slot
  target.call("CLUSTER", "SETSLOT", slot, "IMPORTING", id)

  # Tell the current node to export the slot
  call("CLUSTER", "SETSLOT", slot, "MIGRATING", target.id)

  # Export keys
  done = false
  until done
    keys = call("CLUSTER", "GETKEYSINSLOT", slot, options[:num_keys])

    done = keys.empty?

    keys.each do |key|
      call("MIGRATE", target.ip, target.port, key, DB0, options[:timeout])
    end

    # Tell cluster the location of the new slot
    call("CLUSTER", "SETSLOT", slot, "NODE", target.id)

    friends.each do |node|
      node.call("CLUSTER", "SETSLOT", slot, "NODE", target.id)
    end
  end
end
only_node?() click to toggle source
# File lib/ruster/node.rb, line 169
def only_node?
  parse_info(call("CLUSTER", "INFO"))[:cluster_known_nodes] == "1"
end
port() click to toggle source
# File lib/ruster/node.rb, line 128
def port
  addr.split(":").last
end
read_info_line!(info_line) click to toggle source
# File lib/ruster/node.rb, line 35
def read_info_line!(info_line)
  parts = info_line.split

  @id = parts.shift
  addr = parts.shift
  @flags = parts.shift.split(",")
  @addr = addr unless @flags.include?("myself")
  @master_id = parts.shift
  @ping_epoch = parts.shift.to_i
  @pong_epoch = parts.shift.to_i
  @config_epoch = parts.shift.to_i
  @state = parts.shift
  @slots = []
  @migrating = {}
  @importing = {}

  parts.each do |slots|
    case slots
    when /^(\d+)-(\d+)$/ then @slots << ($1.to_i..$2.to_i)
    when /^\d+$/ then @slots << (slots.to_i..slots.to_i)
    when /^\[(\d+)-([<>])-([a-z0-9]+)\]$/
      case $2
      when ">" then @migrating[$1.to_i] = $3
      when "<" then @importing[$1.to_i] = $3
      end
    end
  end
end
replicate(node) click to toggle source
# File lib/ruster/node.rb, line 98
def replicate(node)
  call("CLUSTER", "REPLICATE", node.id)
end
slaves() click to toggle source
# File lib/ruster/node.rb, line 102
def slaves
  call("CLUSTER", "SLAVES", id).map do |line|
    self.class.from_info_line(line)
  end
end
to_s() click to toggle source
# File lib/ruster/node.rb, line 68
def to_s
  "#{addr} [#{id}]"
end