class Multidb::Balancer

Attributes

fallback[RW]

Public Class Methods

current_connection() click to toggle source
# File lib/multidb/balancer.rb, line 109
def current_connection
  Multidb.balancer.current_connection
end
current_connection_name() click to toggle source
# File lib/multidb/balancer.rb, line 113
def current_connection_name
  Multidb.balancer.current_connection_name
end
disconnect!() click to toggle source
# File lib/multidb/balancer.rb, line 117
def disconnect!
  Multidb.balancer.disconnect!
end
new(configuration) click to toggle source
# File lib/multidb/balancer.rb, line 7
def initialize(configuration)
  @candidates = {}.with_indifferent_access
  @default_configuration = configuration

  return unless @default_configuration

  append(@default_configuration.raw_configuration[:databases] || {})

  @fallback = if @default_configuration.raw_configuration.include?(:fallback)
                @default_configuration.raw_configuration[:fallback]
              elsif defined?(Rails)
                %w[development test].include?(Rails.env)
              else
                false
              end

  @default_candidate = Candidate.new('default', @default_configuration.default_handler)

  @candidates[:default] = [@default_candidate] unless @candidates.include?(:default)
end
use(name, &block) click to toggle source
# File lib/multidb/balancer.rb, line 105
def use(name, &block)
  Multidb.balancer.use(name, &block)
end

Public Instance Methods

append(databases) click to toggle source
# File lib/multidb/balancer.rb, line 28
def append(databases)
  databases.each_pair do |name, config|
    configs = config.is_a?(Array) ? config : [config]
    configs.each do |cfg|
      if cfg['alias']
        @candidates[name] = @candidates[cfg['alias']]
        next
      end

      candidate = Candidate.new(name, @default_configuration.default_adapter.merge(cfg))
      @candidates[name] ||= []
      @candidates[name].push(candidate)
    end
  end
end
current_connection() click to toggle source
# File lib/multidb/balancer.rb, line 88
def current_connection
  if Thread.current[:multidb]
    Thread.current[:multidb][:connection]
  else
    @default_candidate.connection
  end
end
current_connection_name() click to toggle source
# File lib/multidb/balancer.rb, line 96
def current_connection_name
  if Thread.current[:multidb]
    Thread.current[:multidb][:connection_name]
  else
    :default
  end
end
disconnect!() click to toggle source
# File lib/multidb/balancer.rb, line 44
def disconnect!
  @candidates.values.flatten.each(&:disconnect!)
end
get(name) { |candidate| ... } click to toggle source
# File lib/multidb/balancer.rb, line 48
def get(name, &_block)
  candidates = @candidates[name]
  candidates ||= @fallback ? @candidates[:default] : []

  raise ArgumentError, "No such database connection '#{name}'" if candidates.empty?

  candidate = candidates.respond_to?(:sample) ? candidates.sample : candidates[rand(candidates.length)]

  block_given? ? yield(candidate) : candidate
end
use(name) { || ... } click to toggle source
# File lib/multidb/balancer.rb, line 59
def use(name, &_block)
  result = nil
  get(name) do |candidate|
    if block_given?
      candidate.connection do |connection|
        previous_configuration = Thread.current[:multidb]
        Thread.current[:multidb] = {
          connection: connection,
          connection_name: name
        }
        begin
          result = yield
          result = result.to_a if result.is_a?(ActiveRecord::Relation)
        ensure
          Thread.current[:multidb] = previous_configuration
        end
        result
      end
    else
      Thread.current[:multidb] = {
        connection: candidate.connection,
        connection_name: name
      }
      result = candidate.connection
    end
  end
  result
end