class Clandestined::Cluster

Attributes

hash_function[R]
nodes[R]
replicas[R]
rings[R]
seed[R]
zone_members[R]
zones[R]

Public Class Methods

new(cluster_config=nil, replicas=2, seed=0) click to toggle source
# File lib/clandestined/cluster.rb, line 15
def initialize(cluster_config=nil, replicas=2, seed=0)
  @seed = seed

  @replicas = replicas
  @nodes = Hash[]
  @zones = []
  @zone_members = Hash[]
  @rings = Hash[]

  if cluster_config
    cluster_config.each do |node, node_data|
      name = node_data['name']
      zone = node_data['zone']
      add_zone(zone)
      add_node(node, zone, name)
    end
  end
end

Public Instance Methods

add_node(node_id, node_zone=nil, node_name=nil) click to toggle source
# File lib/clandestined/cluster.rb, line 54
def add_node(node_id, node_zone=nil, node_name=nil)
  if nodes.include?(node_id)
    raise ArgumentError, 'Node with id #{node_id} already exists'
  end
  add_zone(node_zone)
  unless rings.has_key?(node_zone)
    @rings[node_zone] = RendezvousHash.new(nil, seed)
  end
  @rings[node_zone].add_node(node_id)
  @nodes[node_id] = node_name
  (@zone_members[node_zone] ||= []) << node_id
end
add_zone(zone) click to toggle source
# File lib/clandestined/cluster.rb, line 34
def add_zone(zone)
  @zones.push(zone) unless zones.include?(zone)
  @zone_members[zone] ||= []
  @zones.sort!
end
find_nodes(search_key, offset=nil) click to toggle source
# File lib/clandestined/cluster.rb, line 80
def find_nodes(search_key, offset=nil)
  nodes = []
  unless offset
    offset = search_key.split('').inject(0) { |s, c| s += c[0,1].unpack('c')[0] }
  end
  for i in (0...replicas)
    zone = zones[(i + offset.to_i) % zones.length]
    nodes << rings[zone].find_node(search_key)
  end
  nodes
end
find_nodes_by_index(product_id, block_index) click to toggle source
# File lib/clandestined/cluster.rb, line 92
def find_nodes_by_index(product_id, block_index)
  offset = (product_id.to_i + block_index.to_i) % zones.length
  search_key = "#{product_id}-#{block_index}"
  find_nodes(search_key, offset)
end
node_name(node_id) click to toggle source
# File lib/clandestined/cluster.rb, line 76
def node_name(node_id)
  nodes[node_id]
end
remove_node(node_id, node_zone=nil, node_name=nil) click to toggle source
# File lib/clandestined/cluster.rb, line 67
def remove_node(node_id, node_zone=nil, node_name=nil)
  @rings[node_zone].remove_node(node_id)
  @nodes.delete(node_id)
  @zone_members[node_zone].delete(node_id)
  if zone_members[node_zone].length == 0
    remove_zone(node_zone)
  end
end
remove_zone(zone) click to toggle source
# File lib/clandestined/cluster.rb, line 40
def remove_zone(zone)
  if zones.include?(zone)
    @zones.delete(zone)
    for member in zone_members[zone]
      @nodes.delete(member)
    end
    @zones.sort!
    @rings.delete(zone)
    @zone_members.delete(zone)
  else
    raise ArgumentError, "No such zone #{zone} to remove"
  end
end