class AdvancedConnection::ActiveRecordExt::ConnectionPool::IdleManager::IdleManager

Attributes

interval[RW]
logger[R]

Public Class Methods

new(pool, interval) click to toggle source
# File lib/advanced_connection/active_record_ext/connection_pool/idle_manager.rb, line 36
def initialize(pool, interval)
  @pool     = pool
  @interval = interval.to_i
  @logger   = ActiveSupport::Logger.new(Rails.root.join('log', 'idle_manager.log'))

  @logger.level = AdvancedConnection.idle_manager_log_level || ::Logger::INFO
end

Public Instance Methods

dump_connections() click to toggle source
# File lib/advanced_connection/active_record_ext/connection_pool/idle_manager.rb, line 55
def dump_connections
  return unless (stats_dump = Rails.root.join('tmp', 'dump-connections.txt')).exist?

  log_info "Dumping connections"

  id_size = object_id.to_s.size
  @logger.info(format("%3s: %#{id_size}s\t%9s\t%9s\t%4s\t%s", 'IDX', 'OID', 'AGE', 'IDLE', 'ACTV', 'OWNER'))

  @pool.connections.dup.each_with_index do |connection, index|
    if connection.in_use?
      thread_id    = reserved_connections.index(connection) || 0
      thread_hexid = "0x" << (thread_id << 1).to_s(16)
    end

    @logger.info(format("%3d: %#{id_size}d\t%9d\t%9d\t%4s\t%s",
                        index, connection.object_id,
                        connection.instance_age, connection.idle_time,
                        connection.in_use?.to_s, thread_hexid))
  end

  !!(stats_dump.unlink rescue true) # rubocop:disable Style/RescueModifier
end
idle_stats() click to toggle source
# File lib/advanced_connection/active_record_ext/connection_pool/idle_manager.rb, line 78
def idle_stats
  stats = @pool.pool_statistics
  format("[Act: %d / Avail: %d (%d idle) / Total: %d]",
         stats.active, stats.available, stats.idle, stats.total)
end
reserved_connections() click to toggle source
# File lib/advanced_connection/active_record_ext/connection_pool/idle_manager.rb, line 50
def reserved_connections
  reserved = @pool.instance_variable_get(:@reserved_connections).dup
  Hash[reserved.keys.zip(reserved.values)]
end
run() click to toggle source
# File lib/advanced_connection/active_record_ext/connection_pool/idle_manager.rb, line 102
def run
  return unless @interval > 0

  Thread.new(@pool, @interval) do |pool, interval|
    Thread.current.name = self.class.name if Thread.current.respond_to? :name=

    begin
      pool.release_connection if pool.active_connection?
    rescue StandardError => e
      log_error "#{e.class.name}: #{e.message}\n\t#{e.backtrace.join("\n\t")}"
    end

    log_info("starting idle manager; running every #{interval} seconds")
    last_run = nil

    loop {
      sleep interval

      last_run = safe_timed_run(last_run) do
        dump_connections
        pool.remove_idle_connections
      end
    }
  end

  self
end
safe_timed_run(last_run = nil) { || ... } click to toggle source
# File lib/advanced_connection/active_record_ext/connection_pool/idle_manager.rb, line 84
def safe_timed_run(last_run = nil)
  return unless block_given?

  log_debug "last run was #{Time.now - last_run} seconds ago" if last_run

  begin
    start = Time.now
    yield
  rescue StandardError => e
    log_error "#{e.class.name}: #{e.message}\n\t#{e.backtrace.join("\n\t")}"
  ensure
    finish = ((last_run = Time.now) - start).round(6)
    log_info("finished idle connection tasks in #{finish} seconds")
  end

  last_run
end