class KVMultiplex::Multiplexer

Attributes

logger[R]

Public Class Methods

new(delimiter: ".", logger: Logger.new) click to toggle source
# File lib/kvmultiplex/multiplexer.rb, line 10
def initialize(delimiter: ".", logger: Logger.new)
  @logger = logger
  @delimiter = delimiter.dup

  @providers = {}
end

Public Instance Methods

find_providers_for_key(key) click to toggle source
# File lib/kvmultiplex/multiplexer.rb, line 86
def find_providers_for_key(key)
  logger.debug "Key lookup for '#{key.inspect}'."

  key =
    if key.is_a?(String)
      key.split(@delimiter).freeze
    elsif key.is_a?(Array) && key.all? { |i| i.is_a?(String) }
      key.map(&:to_s).freeze
    else
      raise "key must be a String or array of Strings."
    end

  key_length = key.size

  longest = -1
  longest_prefix = nil
  matched_providers = nil

  @providers.each_pair do |prefix, providers|
    lcs_length = Diff::LCS.LCS(key, prefix).length

    next unless [longest, lcs_length].max == prefix.length

    longest = lcs_length
    longest_prefix = prefix
    matched_providers = providers
    break if key_length == lcs_length # we've matched exactly
  end

  if matched_providers.nil?
    [nil, nil, key]
  else
    subkey = key - longest_prefix

    [matched_providers, subkey, key]
  end
end
get(key) click to toggle source
# File lib/kvmultiplex/multiplexer.rb, line 44
def get(key)
  providers, subkey, full_key = find_providers_for_key(key)

  if providers.nil? || providers.empty?
    logger.warn "No providers for '#{full_key.inspect}'."
    nil
  else
    ret =
      providers.lazy
               .map  { |provider| provider.get(subkey, full_key) }
               .find { |v| !v.nil? }
    logger.warn "No values found for '#{full_key.inspect}'." if ret.nil?

    ret
  end
end
get!(key) click to toggle source
# File lib/kvmultiplex/multiplexer.rb, line 38
def get!(key)
  ret = get(key)
  raise "Value not found for key: #{key}" if ret.nil?
  ret
end
register(prefix, provider, prepend: false) click to toggle source
# File lib/kvmultiplex/multiplexer.rb, line 17
def register(prefix, provider, prepend: false)
  raise "provider must be a KVMultiplex::Provider." unless provider.is_a?(KVMultiplex::Provider)

  prefix =
    if prefix.is_a?(String)
      prefix.split(@delimiter).freeze
    elsif prefix.is_a?(Array) && prefix.all? { |i| i.is_a?(String) }
      prefix.map { |i| i.to_s.dup }.freeze
    else
      raise "prefix must be a String or array of Strings."
    end

  @providers[prefix] ||= []

  if prepend
    @providers[prefix].unshift provider
  else
    @providers[prefix].push provider
  end
end
set(key, value) click to toggle source
# File lib/kvmultiplex/multiplexer.rb, line 61
def set(key, value)
  providers, subkey, full_key = find_providers_for_key(key)

  if providers.nil? || providers.empty?
    logger.warn "No providers for '#{full_key.inspect}'."
    nil
  else
    logger.warn "Multiple providers found for '#{full_key.inspect}'; this might cause surprising behavior!" \
      unless providers.size == 1

    ret = providers.find do |provider|
      logger.debug "Attempting to set into #{provider}."
      p_ret = provider.set(subkey, full_key, value)

      logger.debug "Failed to set into #{provider}." if p_ret.nil?
      !p_ret.nil?
    end

    raise "No provider able to set '#{full_key.inspect}'." unless ret
    ret
  end

  value
end