Class: MysqlFramework::MysqlConnectionPool

Inherits:
Object
  • Object
show all
Defined in:
lib/mysql_framework/mysql_connection_pool.rb

Defined Under Namespace

Classes: ConnectionSanitizationError

Constant Summary collapse

CLEAN_IDLE_CONNECTIONS_THREAD_NAME =
'clean-idle-connections'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options) ⇒ void

Initializes a connection pool instance with MySQL client options.

Parameters:

  • options (Hash)

    MySQL client options passed to each pooled connection



17
18
19
20
# File 'lib/mysql_framework/mysql_connection_pool.rb', line 17

def initialize(options)
  @options = options
  @setup_mutex = Mutex.new
end

Instance Attribute Details

#connectionsObject (readonly)

Returns the value of attribute connections.



11
12
13
# File 'lib/mysql_framework/mysql_connection_pool.rb', line 11

def connections
  @connections
end

Instance Method Details

#check_in(client) ⇒ void

This method returns an undefined value.

Returns a MySQL client back to the pool or closes it when pooling is disabled.

Parameters:

  • client (Mysql2::Client, nil)

    client to return or close



87
88
89
90
91
92
# File 'lib/mysql_framework/mysql_connection_pool.rb', line 87

def check_in(client)
  return if client.nil?

  discard_current_connection! if client.closed?
  connections.checkin
end

#check_outMysql2::Client

Checks out a MySQL client, sanitizing it before use.

Returns:

  • (Mysql2::Client)

    checked-out client

Raises:

  • (ConnectionSanitizationError)

    when sanitization repeatedly fails

  • (Mysql2::Error)

    when checkout or sanitization fails due to MySQL errors



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/mysql_framework/mysql_connection_pool.rb', line 66

def check_out
  sanitization_retries = 0
  begin
    conn = connections.checkout
    sanitize_connection!(conn)
    conn
  rescue ConnectionSanitizationError
    discard_current_connection!
    sanitization_retries += 1
    retry if sanitization_retries <= 1
    raise
  rescue Mysql2::Error
    discard_current_connection!
    raise
  end
end

#disposevoid

This method returns an undefined value.

Disposes of the connection pool and closes pooled connections.



40
41
42
43
44
45
46
# File 'lib/mysql_framework/mysql_connection_pool.rb', line 40

def dispose
  @setup_mutex.synchronize do
    dispose_clean_idle_connections_thread
    connections&.shutdown(&:close)
    @connections = nil
  end
end

#pool_statsHash{Symbol => Integer}

Returns key connection-pool metrics for monitoring.

Returns:

  • (Hash{Symbol => Integer})

    pool size and availability metrics



51
52
53
54
55
56
57
58
59
# File 'lib/mysql_framework/mysql_connection_pool.rb', line 51

def pool_stats
  return { size: 0, available: 0, idle: 0 } if connections.nil?

  {
    size: connections.size,
    available: connections.available,
    idle: connections.idle
  }
end

#setupConnectionPool

Sets up the MySQL connection pool. Idempotent — safe to call more than once.

Returns:

  • (ConnectionPool)

    configured pool



25
26
27
28
29
30
31
32
33
34
35
# File 'lib/mysql_framework/mysql_connection_pool.rb', line 25

def setup
  @setup_mutex.synchronize do
    return if connections

    @connections = ConnectionPool.new(size: max_pool_size, timeout: pool_timeout) do
      Mysql2::Client.new(@options)
    end

    start_clean_idle_connections_thread
  end
end

#with_client(discard_current_pool_connection: false) {|client| ... } ⇒ Object

Yields a MySQL client from the pool, or yields the provided client directly.

Parameters:

  • provided_client (Mysql2::Client, nil)

    existing client to yield without pool checkout

  • discard_current_pool_connection (Boolean) (defaults to: false)

    whether to discard the pooled connection after use

Yields:

  • (client)

    block that performs work with a MySQL client

Yield Parameters:

  • client (Mysql2::Client)

Returns:

  • (Object)

    block result

Raises:

  • (Mysql2::Error)

    re-raises MySQL errors from the block



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/mysql_framework/mysql_connection_pool.rb', line 102

def with_client(discard_current_pool_connection: false)
  sanitization_retries = 0

  begin
    connections.with do |conn|
      sanitize_connection!(conn)
      yield conn
    rescue ConnectionSanitizationError, Mysql2::Error
      discard_current_connection!
      raise
    ensure
      discard_current_connection! if discard_current_pool_connection
    end
  rescue ConnectionSanitizationError
    sanitization_retries += 1
    retry if sanitization_retries <= 1
    raise
  end
end