class ActiveRecord::ConnectionAdapters::MariaDbClusterPoolAdapter

Attributes

available_connections[R]
connections[R]
master_connection[R]

Public Class Methods

adapter_class(master_connection) click to toggle source

Create an anonymous class that extends this one and proxies methods to the pool connections.

# File lib/active_record/connection_adapters/maria_db_cluster_pool_adapter.rb, line 77
        def adapter_class(master_connection)
          # Define methods to proxy to the appropriate pool
          master_methods = []
          master_connection_classes = [AbstractAdapter, Quoting, DatabaseStatements, SchemaStatements]
          master_connection_classes << DatabaseLimits if const_defined?(:DatabaseLimits)
          master_connection_class = master_connection.class
          while ![Object, AbstractAdapter].include?(master_connection_class) do
            master_connection_classes << master_connection_class
            master_connection_class = master_connection_class.superclass
          end
          master_connection_classes.each do |connection_class|
            master_methods.concat(connection_class.public_instance_methods(false))
            master_methods.concat(connection_class.protected_instance_methods(false))
          end
          master_methods.uniq!
          master_methods -= public_instance_methods(false) + protected_instance_methods(false) + private_instance_methods(false)
          master_methods = master_methods.collect{|m| m.to_sym}

          klass = Class.new(self)
          master_methods.each do |method_name|
            klass.class_eval <<-EOS, __FILE__, __LINE__ + 1
              def #{method_name}(*args, &block)
                return proxy_connection_method(master_connection, :#{method_name}, *args, &block)
              end
            EOS
          end

          return klass
        end
new(connection, logger, connections, pool_weights) click to toggle source
Calls superclass method
# File lib/active_record/connection_adapters/maria_db_cluster_pool_adapter.rb, line 117
def initialize(connection, logger, connections, pool_weights)
  # @available_connections = connections.dup.freeze
  @connections = connections.dup.freeze
  @available_connections = []
  @master_connection = connection

  super(connection, logger)

  pool_weights.each_pair do |conn, weight|
    @available_connections[weight] = AvailableConnection.new(conn)
  end
end
visitor_for(pool) click to toggle source

Set the arel visitor on the connections.

# File lib/active_record/connection_adapters/maria_db_cluster_pool_adapter.rb, line 108
def visitor_for(pool)
  # This is ugly, but then again, so is the code in ActiveRecord for setting the arel
  # visitor. There is a note in the code indicating the method signatures should be updated.
  config = pool.spec.config.with_indifferent_access
  adapter = config[:master][:adapter] || config[:pool_adapter]
  MariaDbClusterPool.adapter_class_for(adapter).visitor_for(pool)
end

Public Instance Methods

active?() click to toggle source
# File lib/active_record/connection_adapters/maria_db_cluster_pool_adapter.rb, line 151
def active?
  active = true
  do_to_connections {|conn| active &= conn.active?}
  return active
end
all_connections() click to toggle source

Returns an array of the master connection and the read pool connections

# File lib/active_record/connection_adapters/maria_db_cluster_pool_adapter.rb, line 135
def all_connections
  @connections
end
disconnect!() click to toggle source
# File lib/active_record/connection_adapters/maria_db_cluster_pool_adapter.rb, line 161
def disconnect!
  do_to_connections {|conn| conn.disconnect!}
end
next_usable_connection() click to toggle source
# File lib/active_record/connection_adapters/maria_db_cluster_pool_adapter.rb, line 282
def next_usable_connection
  available = available_connections
  available.each do |a|
    if a != nil
      unless a.failed?
        if a.connection.active?
          @logger.info("New master connection is now : #{a.connection.inspect}") if @logger
          @master_connection = a.connection
          break
        end
      end
    end
  end
end
reconnect!() click to toggle source
# File lib/active_record/connection_adapters/maria_db_cluster_pool_adapter.rb, line 157
def reconnect!
  do_to_connections {|conn| conn.reconnect!}
end
requires_reloading?() click to toggle source
# File lib/active_record/connection_adapters/maria_db_cluster_pool_adapter.rb, line 139
def requires_reloading?
  false
end
reset!() click to toggle source
# File lib/active_record/connection_adapters/maria_db_cluster_pool_adapter.rb, line 165
def reset!
  do_to_connections {|conn| conn.reset!}
end
reset_available_connections() click to toggle source
# File lib/active_record/connection_adapters/maria_db_cluster_pool_adapter.rb, line 260
def reset_available_connections
  @available_connections.each do |a|
    if a != nil
      a.reconnect! rescue nil
    end
  end
end
reset_runtime() click to toggle source
# File lib/active_record/connection_adapters/maria_db_cluster_pool_adapter.rb, line 173
def reset_runtime
  total = 0.0
  do_to_connections {|conn| total += conn.reset_runtime}
  total
end
suppress_connection(conn, expire) click to toggle source

Temporarily remove a connection from the read pool.

# File lib/active_record/connection_adapters/maria_db_cluster_pool_adapter.rb, line 269
def suppress_connection(conn, expire)
  available = available_connections
  available.each do |a|
    if a != nil
      if a.connection == conn
        a.failed_connection = true
        a.expires = expire.seconds.from_now
        @logger.info("Supressing database connection from the pool : #{a.connection.inspect}") if @logger
      end
    end
  end
end
verify!(*ignored) click to toggle source
# File lib/active_record/connection_adapters/maria_db_cluster_pool_adapter.rb, line 169
def verify!(*ignored)
  do_to_connections {|conn| conn.verify!(*ignored)}
end
visitor() click to toggle source
# File lib/active_record/connection_adapters/maria_db_cluster_pool_adapter.rb, line 147
def visitor
  connection.visitor
end
visitor=(visitor) click to toggle source
# File lib/active_record/connection_adapters/maria_db_cluster_pool_adapter.rb, line 143
def visitor=(visitor)
  all_connections.each{|conn| conn.visitor = visitor}
end

Private Instance Methods

do_to_connections() { |conn| ... } click to toggle source

Yield a block to each connection in the pool. If the connection is dead, ignore the error

# File lib/active_record/connection_adapters/maria_db_cluster_pool_adapter.rb, line 323
def do_to_connections
  all_connections.each do |conn|
    begin
      yield(conn)
    rescue => e
      if @logger
        @logger.warn("Error in do_to_connections")
        @logger.warn(e.message)
        @logger.warn(e.backtrace.inspect)
      end
    end
  end
end
proxy_connection_method(connection, method, *args, &block) click to toggle source
# File lib/active_record/connection_adapters/maria_db_cluster_pool_adapter.rb, line 299
def proxy_connection_method(connection, method, *args, &block)
  available_connections
  begin
    connection.send(method, *args, &block)
  rescue ArgumentError
    begin
      connection.send(method, *args)
    rescue ArgumentError
      connection.send(method)
    end
  rescue ActiveRecord::RecordInvalid => e
    throw e
  rescue => e
    # If the statement was a read statement and it wasn't forced against the master connection
    # try to reconnect if the connection is dead and then re-run the statement.
    unless connection.active?
      suppress_connection(@master_connection, 30)
      next_usable_connection
    end
    proxy_connection_method(@master_connection, method, *args, &block)
  end
end