From 25d68fece01141acd8d3f15fb81635ff5b0d81f8 Mon Sep 17 00:00:00 2001 From: Rob Pickerill Date: Tue, 12 Nov 2024 15:55:33 +0000 Subject: [PATCH] include pool settings in cache key Signed-off-by: Rob Pickerill --- pkg/scalers/mysql_scaler.go | 42 ++++++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/pkg/scalers/mysql_scaler.go b/pkg/scalers/mysql_scaler.go index 0ae20863ce2..18dbd1c6566 100644 --- a/pkg/scalers/mysql_scaler.go +++ b/pkg/scalers/mysql_scaler.go @@ -18,13 +18,14 @@ import ( ) var ( - // A map that holds MySQL connection pools, keyed by connection string - connectionPools *kedautil.RefMap[string, *sql.DB] + // A map that holds MySQL connection pools, keyed by connection string, + // max open connections, max idle connections, and max idle time + connectionPools *kedautil.RefMap[mySQLConnectionPoolKey, *sql.DB] ) func init() { // Initialize the global connectionPools map - connectionPools = kedautil.NewRefMap[string, *sql.DB]() + connectionPools = kedautil.NewRefMap[mySQLConnectionPoolKey, *sql.DB]() } type mySQLScaler struct { @@ -53,6 +54,25 @@ type mySQLMetadata struct { ConnMaxIdleTime int `keda:"name=connMaxIdleTime, order=triggerMetadata, optional"` // seconds } +// mySQLConnectionPoolKey is used as a key to store MySQL connection pools in +// the global map +type mySQLConnectionPoolKey struct { + connectionString string + maxOpenConns int + maxIdleConns int + connMaxIdleTime int +} + +// newMySQLConnectionPoolKey creates a new mySQLConnectionPoolKey +func newMySQLConnectionPoolKey(meta *mySQLMetadata) mySQLConnectionPoolKey { + return mySQLConnectionPoolKey{ + connectionString: metadataToConnectionStr(meta), + maxOpenConns: meta.MaxOpenConns, + maxIdleConns: meta.MaxIdleConns, + connMaxIdleTime: meta.ConnMaxIdleTime, + } +} + // NewMySQLScaler creates a new MySQL scaler func NewMySQLScaler(config *scalersconfig.ScalerConfig) (Scaler, error) { metricType, err := GetMetricTargetType(config) @@ -127,10 +147,11 @@ func metadataToConnectionStr(meta *mySQLMetadata) string { // been created, it will create a new connection pool and store it in the // connectionPools map. func getConnectionPool(meta *mySQLMetadata, logger logr.Logger) (*sql.DB, error) { - connStr := metadataToConnectionStr(meta) + key := newMySQLConnectionPoolKey(meta) + // Try to load an existing pool and increment its reference count if found - if pool, ok := connectionPools.Load(connStr); ok { - err := connectionPools.AddRef(connStr) + if pool, ok := connectionPools.Load(key); ok { + err := connectionPools.AddRef(key) if err != nil { logger.Error(err, "Error increasing connection pool reference count") return nil, err @@ -144,8 +165,8 @@ func getConnectionPool(meta *mySQLMetadata, logger logr.Logger) (*sql.DB, error) if err != nil { return nil, err } - err = connectionPools.Store(connStr, newPool, func(db *sql.DB) error { - logger.Info("Closing MySQL connection pool", "connectionString", connStr) + err = connectionPools.Store(key, newPool, func(db *sql.DB) error { + logger.Info("Closing MySQL connection pool", "connectionString", key.connectionString) return db.Close() }) if err != nil { @@ -222,8 +243,9 @@ func (s *mySQLScaler) Close(ctx context.Context) error { // closeGlobalPool closes all MySQL connections in the global pool func (s *mySQLScaler) closeGlobalPool(_ context.Context) error { - connStr := metadataToConnectionStr(s.metadata) - if err := connectionPools.RemoveRef(connStr); err != nil { + key := newMySQLConnectionPoolKey(s.metadata) + + if err := connectionPools.RemoveRef(key); err != nil { s.logger.Error(err, "Error decreasing connection pool reference count") return err }