class RSolr::Cloud::Connection

RSolr connection adapter for SolrCloud

Constants

ZNODE_COLLECTIONS
ZNODE_LIVE_NODES

Public Class Methods

new(zk) click to toggle source
Calls superclass method
# File lib/rsolr/cloud/connection.rb, line 11
def initialize(zk)
  super()
  @zk = zk
  init_live_node_watcher
  init_collections_watcher
  update_urls
end

Public Instance Methods

execute(client, request_context) click to toggle source
Calls superclass method
# File lib/rsolr/cloud/connection.rb, line 19
def execute(client, request_context)
  collection_name = request_context[:collection]
  raise 'The :collection option must be specified.' unless collection_name
  path  = request_context[:path].to_s
  query = request_context[:query]
  query = query ? "?#{query}" : ''
  url   = select_node(collection_name, path == 'update')
  raise RSolr::Cloud::Error::NotEnoughNodes unless url
  request_context[:uri] = RSolr::Uri.create(url).merge(path + query)
  super(client, request_context)
end

Private Instance Methods

active_node?(node) click to toggle source
# File lib/rsolr/cloud/connection.rb, line 127
def active_node?(node)
  @live_nodes[node['node_name']] && node['state'] == 'active'
end
all_nodes(collection_state) click to toggle source
# File lib/rsolr/cloud/connection.rb, line 116
def all_nodes(collection_state)
  nodes = collection_state['shards'].values.map do |shard|
    shard['replicas'].values
  end
  nodes.flatten
end
available_urls(collection_name, collection_state) click to toggle source
# File lib/rsolr/cloud/connection.rb, line 104
def available_urls(collection_name, collection_state)
  leader_urls = []
  all_urls = []
  all_nodes(collection_state).each do |node|
    next unless active_node?(node)
    url = "#{node['base_url']}/#{collection_name}"
    leader_urls << url if leader_node?(node)
    all_urls << url
  end
  [all_urls, leader_urls]
end
collection_state_znode_path(collection_name) click to toggle source
# File lib/rsolr/cloud/connection.rb, line 123
def collection_state_znode_path(collection_name)
  "/collections/#{collection_name}/state.json"
end
init_collection_state_watcher(collection) click to toggle source
# File lib/rsolr/cloud/connection.rb, line 57
def init_collection_state_watcher(collection)
  @zk.register(collection_state_znode_path(collection)) do
    update_collection_state(collection)
    update_urls
  end
  update_collection_state(collection)
end
init_collections_watcher() click to toggle source
# File lib/rsolr/cloud/connection.rb, line 49
def init_collections_watcher
  @zk.register(ZNODE_COLLECTIONS) do
    update_collections
    update_urls
  end
  update_collections
end
init_live_node_watcher() click to toggle source
# File lib/rsolr/cloud/connection.rb, line 41
def init_live_node_watcher
  @zk.register(ZNODE_LIVE_NODES) do
    update_live_nodes
    update_urls
  end
  update_live_nodes
end
leader_node?(node) click to toggle source
# File lib/rsolr/cloud/connection.rb, line 131
def leader_node?(node)
  node['leader'] == 'true'
end
select_node(collection, leader_only = false) click to toggle source
# File lib/rsolr/cloud/connection.rb, line 33
def select_node(collection, leader_only = false)
  if leader_only
    synchronize { @leader_urls[collection].to_a.sample }
  else
    synchronize { @all_urls[collection].to_a.sample }
  end
end
update_collection_state(collection) click to toggle source
# File lib/rsolr/cloud/connection.rb, line 96
def update_collection_state(collection)
  synchronize do
    collection_state_json, _stat =
      @zk.get(collection_state_znode_path(collection), watch: true)
    @collections.merge!(JSON.parse(collection_state_json))
  end
end
update_collections() click to toggle source
# File lib/rsolr/cloud/connection.rb, line 84
def update_collections
  collections = @zk.children(ZNODE_COLLECTIONS, watch: true)
  created = []
  synchronize do
    @collections ||= {}
    deleted = @collections.keys - collections
    created = collections - @collections.keys
    deleted.each { |collection| @collections.delete(collection) }
  end
  created.each { |collection| init_collection_state_watcher(collection) }
end
update_live_nodes() click to toggle source
# File lib/rsolr/cloud/connection.rb, line 75
def update_live_nodes
  synchronize do
    @live_nodes = {}
    @zk.children(ZNODE_LIVE_NODES, watch: true).each do |node|
      @live_nodes[node] = true
    end
  end
end
update_urls() click to toggle source
# File lib/rsolr/cloud/connection.rb, line 65
def update_urls
  synchronize do
    @all_urls = {}
    @leader_urls = {}
    @collections.each do |name, state|
      @all_urls[name], @leader_urls[name] = available_urls(name, state)
    end
  end
end