module AdvancedConnection::ActiveRecordExt::ConnectionPool::IdleManager

Public Instance Methods

checkin_with_last_checked_in(conn) click to toggle source
# File lib/advanced_connection/active_record_ext/connection_pool/idle_manager.rb, line 179
def checkin_with_last_checked_in(conn)
  begin
    if conn.last_checked_out
      previous_checkin, conn.last_checked_in = conn.last_checked_in, Time.now
      idle_manager.log_debug "checking in connection %s at %s (checked out for %.3f seconds)",
                             conn.object_id, conn.last_checked_in,
                             (conn.last_checked_in - conn.last_checked_out).to_f.round(6)
    else
      idle_manager.log_debug "checking in connection #{conn.object_id}"
    end
  ensure
    checkin_without_last_checked_in(conn)
  end
end
idle_check_interval() click to toggle source
# File lib/advanced_connection/active_record_ext/connection_pool/idle_manager.rb, line 171
def idle_check_interval
  @idle_check_interval ||= begin
    spec.config[:idle_check_interval]  || \
    AdvancedConnection.idle_check_interval || \
    max_idle_time
  end.to_i
end
idle_connections() click to toggle source
# File lib/advanced_connection/active_record_ext/connection_pool/idle_manager.rb, line 203
def idle_connections
  @connections.select(&:idle?).sort
end
initialize_with_advanced_connection(spec) click to toggle source
# File lib/advanced_connection/active_record_ext/connection_pool/idle_manager.rb, line 132
def initialize_with_advanced_connection(spec)
  initialize_without_advanced_connection(spec)

  @available = case queue_type
    when :prefer_older   then Queues::OldAgeBiased.new
    when :prefer_younger then Queues::YoungAgeBiased.new
    when :lifo, :stack   then Queues::Stack.new
    when :fifo, :queue   then Queues::FIFO.new
    else
      Rails.logger.warn "Unknown queue_type #{queue_type.inspect} - using standard FIFO instead"
      Queues::FIFO.new
  end

  @idle_manager = IdleManager.new(self, idle_check_interval).tap(&:run)
end
max_idle_connections() click to toggle source
# File lib/advanced_connection/active_record_ext/connection_pool/idle_manager.rb, line 154
def max_idle_connections
  @max_idle_connections ||= begin
    begin
      spec.config.fetch(:max_idle_connections, AdvancedConnection.max_idle_connections).to_i
    rescue FloatDomainError => e
      raise unless e.message =~ /infinity/i
      ::Float::INFINITY
    end
  end
end
max_idle_time() click to toggle source
# File lib/advanced_connection/active_record_ext/connection_pool/idle_manager.rb, line 165
def max_idle_time
  @max_idle_time ||= begin
    spec.config.fetch(:max_idle_time, AdvancedConnection.max_idle_time).to_i
  end
end
pool_statistics() click to toggle source
# File lib/advanced_connection/active_record_ext/connection_pool/idle_manager.rb, line 194
def pool_statistics
  ActiveSupport::OrderedOptions.new.merge(
    total:     (total  = @connections.size),
    idle:      (idle   = @connections.count(&:idle?)),
    active:    (active = @connections.count(&:in_use?)),
    available: (total - active)
  )
end
queue_type() click to toggle source
# File lib/advanced_connection/active_record_ext/connection_pool/idle_manager.rb, line 148
def queue_type
  @queue_type ||= spec.config.fetch(
    :queue_type, AdvancedConnection.connection_pool_queue_type
  ).to_s.downcase.to_sym
end
remove_idle_connections() click to toggle source
# File lib/advanced_connection/active_record_ext/connection_pool/idle_manager.rb, line 207
def remove_idle_connections
  # don't attempt to remove idle connections if we have threads waiting
  if @available.num_waiting > 0
    idle_manager.log_warn "Skipping reap while #{@available.num_waiting} thread(s) are actively waiting on database connections..."
    return
  end

  return unless (candidates = idle_connections.size - max_idle_connections) > 0
  idle_manager.log_info "attempting to reap #{candidates} candidate connections"

  reaped = 0

  synchronize do
    idle_connections[0...candidates].each_with_index { |conn, idx|
      if remove_connection(conn)
        reaped += 1
        idle_manager.log_info "reaped candidate connection #%d id#%d age:%d idle:%d" % [
          idx, conn.object_id, conn.instance_age.to_i, conn.idle_time.to_i
        ]
      else
        idle_manager.log_info "kept candidate connection #%d id#%d age:%d idle:%d" % [
          idx, conn.object_id, conn.instance_age.to_i, conn.idle_time.to_i
        ]
      end
    }
  end

  idle_manager.log_info "reaped #{reaped} of #{candidates} candidate connections"
end

Private Instance Methods

remove_connection(conn) click to toggle source
# File lib/advanced_connection/active_record_ext/connection_pool/idle_manager.rb, line 239
def remove_connection(conn)
  return false if conn.in_use?

  remove(conn.tap { |c| c.disconnect! })
  true
end