Sha256: 4b13de27b9442661acd2471f8c2dc59cdfbbb14dabf7812a625efe0d6c0cab04

Contents?: true

Size: 1.23 KB

Versions: 2

Compression:

Stored size: 1.23 KB

Contents

# frozen_string_literal: true

require_relative '../errors'
require_relative 'node_key'

class Redis
  class Cluster
    # Load and hashify slot info for Redis Cluster Client
    module SlotLoader
      module_function

      def load(nodes)
        info = {}

        nodes.each do |node|
          info = Hash[*fetch_slot_info(node)]
          info.empty? ? next : break
        end

        return info unless info.empty?

        raise CannotConnectError, 'Redis client could not connect to any cluster nodes'
      end

      def fetch_slot_info(node)
        node.call(%i[cluster slots])
            .map { |arr| parse_slot_info(arr, default_ip: node.host) }
            .flatten
      rescue CannotConnectError, ConnectionError, CommandError
        {} # can retry on another node
      end

      def parse_slot_info(arr, default_ip:)
        first_slot, last_slot = arr[0..1]
        slot_range = (first_slot..last_slot).freeze
        arr[2..-1].map { |addr| [stringify_node_key(addr, default_ip), slot_range] }
                  .flatten
      end

      def stringify_node_key(arr, default_ip)
        ip, port = arr
        ip = default_ip if ip.empty? # When cluster is down
        NodeKey.build_from_host_port(ip, port)
      end
    end
  end
end

Version data entries

2 entries across 2 versions & 1 rubygems

Version Path
redis-4.0.3 lib/redis/cluster/slot_loader.rb
redis-4.1.0.beta1 lib/redis/cluster/slot_loader.rb