From 6dc3289772a2f13901fb66d84c5ca616127e9882 Mon Sep 17 00:00:00 2001 From: DanB Date: Sun, 2 Jul 2017 15:25:30 +0200 Subject: [PATCH] StorDB config conn_max_lifetime, fixes #684 --- apier/v2/cdrs_it_test.go | 4 +-- cmd/cgr-engine/cgr-engine.go | 2 +- cmd/cgr-loader/cgr-loader.go | 6 ++-- config/config.go | 4 +++ config/config_defaults.go | 6 ++-- config/config_json_test.go | 19 ++++++----- config/libconfig_json.go | 1 + data/conf/cgrates/cgrates.json | 62 ++++++++++++++++------------------ engine/libtest.go | 2 +- engine/loader_it_test.go | 3 +- engine/storage_cdrs_it_test.go | 6 ++-- engine/storage_map.go | 1 - engine/storage_mongo_datadb.go | 1 - engine/storage_mysql.go | 9 ++--- engine/storage_postgres.go | 5 +-- engine/storage_redis.go | 1 - engine/storage_utils.go | 18 +++++----- engine/stordb_it_test.go | 4 +-- 18 files changed, 79 insertions(+), 75 deletions(-) diff --git a/apier/v2/cdrs_it_test.go b/apier/v2/cdrs_it_test.go index b8374ed54..c8ffb7e6e 100644 --- a/apier/v2/cdrs_it_test.go +++ b/apier/v2/cdrs_it_test.go @@ -103,10 +103,10 @@ func testV2CDRsInjectUnratedCdr(t *testing.T) { switch cdrsConfDIR { case "cdrsv2mysql": db, err = engine.NewMySQLStorage(cdrsCfg.StorDBHost, cdrsCfg.StorDBPort, cdrsCfg.StorDBName, cdrsCfg.StorDBUser, cdrsCfg.StorDBPass, - cdrsCfg.StorDBMaxOpenConns, cdrsCfg.StorDBMaxIdleConns) + cdrsCfg.StorDBMaxOpenConns, cdrsCfg.StorDBMaxIdleConns, cdrsCfg.StorDBConnMaxLifetime) case "cdrsv2psql": db, err = engine.NewPostgresStorage(cdrsCfg.StorDBHost, cdrsCfg.StorDBPort, cdrsCfg.StorDBName, cdrsCfg.StorDBUser, cdrsCfg.StorDBPass, - cdrsCfg.StorDBMaxOpenConns, cdrsCfg.StorDBMaxIdleConns) + cdrsCfg.StorDBMaxOpenConns, cdrsCfg.StorDBMaxIdleConns, cdrsCfg.StorDBConnMaxLifetime) case "cdrsv2mongo": db, err = engine.NewMongoStorage(cdrsCfg.StorDBHost, cdrsCfg.StorDBPort, cdrsCfg.StorDBName, cdrsCfg.StorDBUser, cdrsCfg.StorDBPass, utils.StorDB, cdrsCfg.StorDBCDRSIndexes, nil, 10) diff --git a/cmd/cgr-engine/cgr-engine.go b/cmd/cgr-engine/cgr-engine.go index 2ba886aec..3118a9166 100644 --- a/cmd/cgr-engine/cgr-engine.go +++ b/cmd/cgr-engine/cgr-engine.go @@ -677,7 +677,7 @@ func main() { } if cfg.RALsEnabled || cfg.CDRSEnabled || cfg.SchedulerEnabled { // Only connect to storDb if necessary storDb, err := engine.ConfigureStorStorage(cfg.StorDBType, cfg.StorDBHost, cfg.StorDBPort, - cfg.StorDBName, cfg.StorDBUser, cfg.StorDBPass, cfg.DBDataEncoding, cfg.StorDBMaxOpenConns, cfg.StorDBMaxIdleConns, cfg.StorDBCDRSIndexes) + cfg.StorDBName, cfg.StorDBUser, cfg.StorDBPass, cfg.DBDataEncoding, cfg.StorDBMaxOpenConns, cfg.StorDBMaxIdleConns, cfg.StorDBConnMaxLifetime, cfg.StorDBCDRSIndexes) if err != nil { // Cannot configure logger database, show stopper utils.Logger.Crit(fmt.Sprintf("Could not configure logger database: %s exiting!", err)) return diff --git a/cmd/cgr-loader/cgr-loader.go b/cmd/cgr-loader/cgr-loader.go index cb3642978..efa019d87 100644 --- a/cmd/cgr-loader/cgr-loader.go +++ b/cmd/cgr-loader/cgr-loader.go @@ -188,7 +188,7 @@ func main() { log.Fatal(err) } storDB, err := engine.ConfigureStorStorage(*stor_db_type, *stor_db_host, *stor_db_port, *stor_db_name, *stor_db_user, *stor_db_pass, *dbdata_encoding, - cgrConfig.StorDBMaxOpenConns, cgrConfig.StorDBMaxIdleConns, cgrConfig.StorDBCDRSIndexes) + cgrConfig.StorDBMaxOpenConns, cgrConfig.StorDBMaxIdleConns, cgrConfig.StorDBConnMaxLifetime, cgrConfig.StorDBCDRSIndexes) if err != nil { log.Fatal(err) } @@ -203,10 +203,10 @@ func main() { if *fromStorDb { dataDB, errDataDB = engine.ConfigureDataStorage(*datadb_type, *datadb_host, *datadb_port, *datadb_name, *datadb_user, *datadb_pass, *dbdata_encoding, cgrConfig.CacheConfig, *loadHistorySize) storDb, errStorDb = engine.ConfigureLoadStorage(*stor_db_type, *stor_db_host, *stor_db_port, *stor_db_name, *stor_db_user, *stor_db_pass, *dbdata_encoding, - cgrConfig.StorDBMaxOpenConns, cgrConfig.StorDBMaxIdleConns, cgrConfig.StorDBCDRSIndexes) + cgrConfig.StorDBMaxOpenConns, cgrConfig.StorDBMaxIdleConns, cgrConfig.StorDBConnMaxLifetime, cgrConfig.StorDBCDRSIndexes) } else if *toStorDb { // Import from csv files to storDb storDb, errStorDb = engine.ConfigureLoadStorage(*stor_db_type, *stor_db_host, *stor_db_port, *stor_db_name, *stor_db_user, *stor_db_pass, *dbdata_encoding, - cgrConfig.StorDBMaxOpenConns, cgrConfig.StorDBMaxIdleConns, cgrConfig.StorDBCDRSIndexes) + cgrConfig.StorDBMaxOpenConns, cgrConfig.StorDBMaxIdleConns, cgrConfig.StorDBConnMaxLifetime, cgrConfig.StorDBCDRSIndexes) } else { // Default load from csv files to dataDb dataDB, errDataDB = engine.ConfigureDataStorage(*datadb_type, *datadb_host, *datadb_port, *datadb_name, *datadb_user, *datadb_pass, *dbdata_encoding, cgrConfig.CacheConfig, *loadHistorySize) } diff --git a/config/config.go b/config/config.go index 9d5d49b4a..ebb40fc27 100644 --- a/config/config.go +++ b/config/config.go @@ -192,6 +192,7 @@ type CGRConfig struct { StorDBPass string // The user's password. StorDBMaxOpenConns int // Maximum database connections opened StorDBMaxIdleConns int // Maximum idle connections to keep opened + StorDBConnMaxLifetime int StorDBCDRSIndexes []string DBDataEncoding string // The encoding used to store object data in strings: CacheConfig *CacheConfig @@ -678,6 +679,9 @@ func (self *CGRConfig) loadFromJsonCfg(jsnCfg *CgrJsonCfg) error { if jsnStorDbCfg.Max_idle_conns != nil { self.StorDBMaxIdleConns = *jsnStorDbCfg.Max_idle_conns } + if jsnStorDbCfg.Conn_max_lifetime != nil { + self.StorDBConnMaxLifetime = *jsnStorDbCfg.Conn_max_lifetime + } if jsnStorDbCfg.Cdrs_indexes != nil { self.StorDBCDRSIndexes = *jsnStorDbCfg.Cdrs_indexes } diff --git a/config/config_defaults.go b/config/config_defaults.go index ed21f6db7..db15c140f 100644 --- a/config/config_defaults.go +++ b/config/config_defaults.go @@ -102,11 +102,13 @@ const CGRATES_CFG_JSON = ` "db_name": "cgrates", // stor database name "db_user": "cgrates", // username to use when connecting to stordb "db_password": "", // password to use when connecting to stordb - "max_open_conns": 100, // maximum database connections opened - "max_idle_conns": 10, // maximum database connections idle + "max_open_conns": 100, // maximum database connections opened, not applying for mongo + "max_idle_conns": 10, // maximum database connections idle, not applying for mongo + "conn_max_lifetime": 0, // maximum amount of time in seconds a connection may be reused (0 for unlimited), not applying for mongo "cdrs_indexes": [], // indexes on cdrs table to speed up queries, used only in case of mongo }, + "rals": { "enabled": false, // enable Rater service: "cdrstats_conns": [], // address where to reach the cdrstats service, empty to disable stats functionality: <""|*internal|x.y.z.y:1234> diff --git a/config/config_json_test.go b/config/config_json_test.go index a5ca676ad..4e18728df 100644 --- a/config/config_json_test.go +++ b/config/config_json_test.go @@ -133,15 +133,16 @@ func TestDfDbJsonCfg(t *testing.T) { t.Error("Received: ", cfg) } eCfg = &DbJsonCfg{ - Db_type: utils.StringPointer("mysql"), - Db_host: utils.StringPointer("127.0.0.1"), - Db_port: utils.IntPointer(3306), - Db_name: utils.StringPointer("cgrates"), - Db_user: utils.StringPointer("cgrates"), - Db_password: utils.StringPointer(""), - Max_open_conns: utils.IntPointer(100), - Max_idle_conns: utils.IntPointer(10), - Cdrs_indexes: utils.StringSlicePointer([]string{}), + Db_type: utils.StringPointer("mysql"), + Db_host: utils.StringPointer("127.0.0.1"), + Db_port: utils.IntPointer(3306), + Db_name: utils.StringPointer("cgrates"), + Db_user: utils.StringPointer("cgrates"), + Db_password: utils.StringPointer(""), + Max_open_conns: utils.IntPointer(100), + Max_idle_conns: utils.IntPointer(10), + Conn_max_lifetime: utils.IntPointer(0), + Cdrs_indexes: utils.StringSlicePointer([]string{}), } if cfg, err := dfCgrJsonCfg.DbJsonCfg(STORDB_JSN); err != nil { t.Error(err) diff --git a/config/libconfig_json.go b/config/libconfig_json.go index ffa42b9aa..c27ef9f1a 100644 --- a/config/libconfig_json.go +++ b/config/libconfig_json.go @@ -65,6 +65,7 @@ type DbJsonCfg struct { Db_password *string Max_open_conns *int // Used only in case of storDb Max_idle_conns *int + Conn_max_lifetime *int // Used only in case of storDb Load_history_size *int // Used in case of dataDb to limit the length of the loads history Cdrs_indexes *[]string } diff --git a/data/conf/cgrates/cgrates.json b/data/conf/cgrates/cgrates.json index 9cf7b50d7..143522cb1 100644 --- a/data/conf/cgrates/cgrates.json +++ b/data/conf/cgrates/cgrates.json @@ -45,6 +45,7 @@ // "reverse_aliases": {"limit": 10000, "ttl":"0s", "precache": false}, // control reverse aliases index caching // "derived_chargers": {"limit": 10000, "ttl":"0s", "precache": false}, // control derived charging rule caching // "resource_limits": {"limit": 10000, "ttl":"0s", "precache": false}, // control resource limits caching +// "timings": {"limit": 10000, "ttl":"0s", "precache": false}, // control timings caching // }, @@ -81,8 +82,9 @@ // "db_name": "cgrates", // stor database name // "db_user": "cgrates", // username to use when connecting to stordb // "db_password": "", // password to use when connecting to stordb -// "max_open_conns": 100, // maximum database connections opened -// "max_idle_conns": 10, // maximum database connections idle +// "max_open_conns": 100, // maximum database connections opened, not applying for mongo +// "max_idle_conns": 10, // maximum database connections idle, not applying for mongo +// "conn_max_lifetime": 0, // maximum amount of time in seconds a connection may be reused (0 for unlimited), not applying for mongo // "cdrs_indexes": [], // indexes on cdrs table to speed up queries, used only in case of mongo // }, @@ -116,7 +118,7 @@ // "pubsubs_conns": [], // address where to reach the pubusb service, empty to disable pubsub functionality: <""|*internal|x.y.z.y:1234> // "users_conns": [], // address where to reach the user service, empty to disable user profile functionality: <""|*internal|x.y.z.y:1234> // "aliases_conns": [], // address where to reach the aliases service, empty to disable aliases functionality: <""|*internal|x.y.z.y:1234> -// "cdrstats_conns": [], // address where to reach the cdrstats service, empty to disable stats functionality<""|*internal|x.y.z.y:1234> +// "cdrstats_conns": [], // address where to reach the cdrstats service, empty to disable stats functionality: <""|*internal|x.y.z.y:1234> // "online_cdr_exports":[], // list of CDRE profiles to use for real-time CDR exports // }, @@ -236,6 +238,7 @@ // "min_call_duration": "0s", // only authorize calls with allowed duration higher than this // "max_call_duration": "3h", // maximum call duration a prepaid call can last // "session_ttl": "0s", // time after a session with no updates is terminated, not defined by default +// //"session_ttl_max_delay": "", // activates session_ttl randomization and limits the maximum possible delay // //"session_ttl_last_used": "", // tweak LastUsed for sessions timing-out, not defined by default // //"session_ttl_usage": "", // tweak Usage for sessions timing-out, not defined by default // "session_indexes": [], // index sessions based on these fields for GetActiveSessions API @@ -259,7 +262,7 @@ // "cdrs_conns": [ // {"address": "*internal"} // address where to reach CDR Server, empty to disable CDR capturing <*internal|x.y.z.y:1234> // ], -// "rls_conns": [], // address where to reach the ResourceLimiter service, empty to disable stats functionality: <""|*internal|x.y.z.y:1234> +// "rls_conns": [], // address where to reach the ResourceLimiter service, empty to disable functionality: <""|*internal|x.y.z.y:1234> // "create_cdr": false, // create CDR out of events and sends them to CDRS component // "extra_fields": [], // extra fields to store in auth/CDRs when creating them // "debit_interval": "10s", // interval to perform debits on. @@ -286,6 +289,7 @@ // "cdrs_conns": [ // {"address": "*internal"} // address where to reach CDR Server, empty to disable CDR capturing <*internal|x.y.z.y:1234> // ], +// "rls_conns": [], // address where to reach the ResourceLimiter service, empty to disable functionality: <""|*internal|x.y.z.y:1234> // "create_cdr": false, // create CDR out of events and sends them to CDRS component // "debit_interval": "10s", // interval to perform debits on. // "min_call_duration": "0s", // only authorize calls with allowed duration higher than this @@ -330,35 +334,28 @@ // "origin_realm": "cgrates.org", // diameter Origin-Realm AVP used in replies // "vendor_id": 0, // diameter Vendor-Id AVP used in replies // "product_name": "CGRateS", // diameter Product-Name AVP used in replies -// "request_processors": [ -// { -// "id": "*default", // formal identifier of this processor -// "dry_run": false, // do not send the events to SMG, just log them -// "publish_event": false, // if enabled, it will publish internal event to pubsub -// "request_filter": "Subscription-Id>Subscription-Id-Type(0)", // filter requests processed by this processor -// "flags": [], // flags to influence processing behavior -// "continue_on_success": false, // continue to the next template if executed -// "append_cca": true, // when continuing will append cca fields to the previous ones -// "ccr_fields":[ // import content_fields template, tag will match internally CDR field, in case of .csv value will be represented by index of the field value -// {"tag": "TOR", "field_id": "ToR", "type": "*composed", "value": "^*voice", "mandatory": true}, -// {"tag": "OriginID", "field_id": "OriginID", "type": "*composed", "value": "Session-Id", "mandatory": true}, -// {"tag": "RequestType", "field_id": "RequestType", "type": "*composed", "value": "^*users", "mandatory": true}, -// {"tag": "Direction", "field_id": "Direction", "type": "*composed", "value": "^*out", "mandatory": true}, -// {"tag": "Tenant", "field_id": "Tenant", "type": "*composed", "value": "^*users", "mandatory": true}, -// {"tag": "Category", "field_id": "Category", "type": "*composed", "value": "^call", "mandatory": true}, -// {"tag": "Account", "field_id": "Account", "type": "*composed", "value": "^*users", "mandatory": true}, -// {"tag": "Subject", "field_id": "Subject", "type": "*composed", "value": "^*users", "mandatory": true}, -// {"tag": "Destination", "field_id": "Destination", "type": "*composed", "value": "Service-Information>IN-Information>Real-Called-Number", "mandatory": true}, -// {"tag": "SetupTime", "field_id": "SetupTime", "type": "*composed", "value": "Event-Timestamp", "mandatory": true}, -// {"tag": "AnswerTime", "field_id": "AnswerTime", "type": "*composed", "value": "Event-Timestamp", "mandatory": true}, -// {"tag": "Usage", "field_id": "Usage", "type": "*handler", "handler_id": "*ccr_usage", "mandatory": true}, -// {"tag": "SubscriberID", "field_id": "SubscriberId", "type": "*composed", "value": "Subscription-Id>Subscription-Id-Data", "mandatory": true}, -// ], -// "cca_fields":[ // fields returned in CCA -// {"tag": "GrantedUnits", "field_id": "Granted-Service-Unit>CC-Time", "type": "*handler", "handler_id": "*cca_usage", "mandatory": true}, -// ], -// }, +// "request_processors": [], +// }, + + +// "radius_agent": { +// "enabled": false, // enables the radius agent: +// "listen_net": "udp", // network to listen on +// "listen_auth": "127.0.0.1:1812", // address where to listen for radius authentication requests +// "listen_acct": "127.0.0.1:1813", // address where to listen for radius accounting requests +// "client_secrets": { // hash containing secrets for clients connecting here <*default|$client_ip> +// "*default": "CGRateS.org" +// }, +// "client_dictionaries": { // per client path towards directory holding additional dictionaries to load (extra to RFC) +// "*default": "/usr/share/cgrates/radius/dict/", // key represents the client IP or catch-all <*default|$client_ip> +// }, +// "sm_generic_conns": [ +// {"address": "*internal"} // connection towards SMG component for session management // ], +// "create_cdr": true, // create CDR out of Accounting-Stop and send it to SMG component +// "cdr_requires_session": false, // only create CDR if there is an active session at terminate +// "timezone": "", // timezone for timestamps where not specified, empty for general defaults <""|UTC|Local|$IANA_TZ_DB> +// "request_processors": [], // }, @@ -389,7 +386,6 @@ // "enabled": false, // starts ResourceLimiter service: . // "cdrstats_conns": [], // address where to reach the cdrstats service, empty to disable stats functionality: <""|*internal|x.y.z.y:1234> // "cache_dump_interval": "0s", // dump cache regularly to dataDB, 0 - dump at start/shutdown: <""|*never|$dur> -// "usage_ttl": "3h", // expire usage records if older than this duration <""|*never|$dur> // }, diff --git a/engine/libtest.go b/engine/libtest.go index 064647608..1962a0ba4 100644 --- a/engine/libtest.go +++ b/engine/libtest.go @@ -48,7 +48,7 @@ func InitDataDb(cfg *config.CGRConfig) error { func InitStorDb(cfg *config.CGRConfig) error { storDb, err := ConfigureLoadStorage(cfg.StorDBType, cfg.StorDBHost, cfg.StorDBPort, cfg.StorDBName, cfg.StorDBUser, cfg.StorDBPass, cfg.DBDataEncoding, - cfg.StorDBMaxOpenConns, cfg.StorDBMaxIdleConns, cfg.StorDBCDRSIndexes) + cfg.StorDBMaxOpenConns, cfg.StorDBMaxIdleConns, cfg.StorDBConnMaxLifetime, cfg.StorDBCDRSIndexes) if err != nil { return err } diff --git a/engine/loader_it_test.go b/engine/loader_it_test.go index 64ea72254..e4d1b4b6b 100644 --- a/engine/loader_it_test.go +++ b/engine/loader_it_test.go @@ -62,7 +62,8 @@ func TestLoaderITConnDataDbs(t *testing.T) { // Create/reset storage tariff plan tables, used as database connectin establishment also func TestLoaderITCreateStorTpTables(t *testing.T) { - db, err := NewMySQLStorage(lCfg.StorDBHost, lCfg.StorDBPort, lCfg.StorDBName, lCfg.StorDBUser, lCfg.StorDBPass, lCfg.StorDBMaxOpenConns, lCfg.StorDBMaxIdleConns) + db, err := NewMySQLStorage(lCfg.StorDBHost, lCfg.StorDBPort, lCfg.StorDBName, + lCfg.StorDBUser, lCfg.StorDBPass, lCfg.StorDBMaxOpenConns, lCfg.StorDBMaxIdleConns, lCfg.StorDBConnMaxLifetime) if err != nil { t.Error("Error on opening database connection: ", err) return diff --git a/engine/storage_cdrs_it_test.go b/engine/storage_cdrs_it_test.go index 44363bd9d..4483b8eae 100644 --- a/engine/storage_cdrs_it_test.go +++ b/engine/storage_cdrs_it_test.go @@ -85,7 +85,7 @@ func testSetCDR(cfg *config.CGRConfig) error { return err } cdrStorage, err := ConfigureCdrStorage(cfg.StorDBType, cfg.StorDBHost, cfg.StorDBPort, cfg.StorDBName, cfg.StorDBUser, cfg.StorDBPass, - cfg.StorDBMaxOpenConns, cfg.StorDBMaxIdleConns, cfg.StorDBCDRSIndexes) + cfg.StorDBMaxOpenConns, cfg.StorDBMaxIdleConns, cfg.StorDBConnMaxLifetime, cfg.StorDBCDRSIndexes) if err != nil { return err } @@ -195,7 +195,7 @@ func testSMCosts(cfg *config.CGRConfig) error { return fmt.Errorf("testSMCosts #1 err: %v", err) } cdrStorage, err := ConfigureCdrStorage(cfg.StorDBType, cfg.StorDBHost, cfg.StorDBPort, cfg.StorDBName, cfg.StorDBUser, cfg.StorDBPass, - cfg.StorDBMaxOpenConns, cfg.StorDBMaxIdleConns, cfg.StorDBCDRSIndexes) + cfg.StorDBMaxOpenConns, cfg.StorDBMaxIdleConns, cfg.StorDBConnMaxLifetime, cfg.StorDBCDRSIndexes) if err != nil { return fmt.Errorf("testSMCosts #2 err: %v", err) } @@ -243,7 +243,7 @@ func testGetCDRs(cfg *config.CGRConfig) error { return fmt.Errorf("testGetCDRs #1: %v", err) } cdrStorage, err := ConfigureCdrStorage(cfg.StorDBType, cfg.StorDBHost, cfg.StorDBPort, cfg.StorDBName, cfg.StorDBUser, cfg.StorDBPass, - cfg.StorDBMaxOpenConns, cfg.StorDBMaxIdleConns, cfg.StorDBCDRSIndexes) + cfg.StorDBMaxOpenConns, cfg.StorDBMaxIdleConns, cfg.StorDBConnMaxLifetime, cfg.StorDBCDRSIndexes) if err != nil { return fmt.Errorf("testGetCDRs #2: %v", err) } diff --git a/engine/storage_map.go b/engine/storage_map.go index 5a1c1ead7..c506ea51e 100644 --- a/engine/storage_map.go +++ b/engine/storage_map.go @@ -1461,7 +1461,6 @@ func (ms *MapStorage) GetTiming(id string, skipCache bool, transactionID string) } func (ms *MapStorage) SetTiming(t *utils.TPTiming, transactionID string) error { - fmt.Println("Map") ms.mu.Lock() defer ms.mu.Unlock() result, err := ms.ms.Marshal(t) diff --git a/engine/storage_mongo_datadb.go b/engine/storage_mongo_datadb.go index 5f2a86575..0ab10a370 100644 --- a/engine/storage_mongo_datadb.go +++ b/engine/storage_mongo_datadb.go @@ -1934,7 +1934,6 @@ func (ms *MongoStorage) GetTiming(id string, skipCache bool, transactionID strin } func (ms *MongoStorage) SetTiming(t *utils.TPTiming, transactionID string) (err error) { - fmt.Println("Mongo") session, col := ms.conn(colTmg) defer session.Close() _, err = col.Upsert(bson.M{"id": t.ID}, t) diff --git a/engine/storage_mysql.go b/engine/storage_mysql.go index 6e84dc10a..7681d6b7e 100644 --- a/engine/storage_mysql.go +++ b/engine/storage_mysql.go @@ -19,18 +19,18 @@ package engine import ( "fmt" - - _ "github.com/go-sql-driver/mysql" - "github.com/jinzhu/gorm" + "time" "github.com/cgrates/cgrates/utils" + _ "github.com/go-sql-driver/mysql" + "github.com/jinzhu/gorm" ) type MySQLStorage struct { SQLStorage } -func NewMySQLStorage(host, port, name, user, password string, maxConn, maxIdleConn int) (*SQLStorage, error) { +func NewMySQLStorage(host, port, name, user, password string, maxConn, maxIdleConn, connMaxLifetime int) (*SQLStorage, error) { connectString := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8&loc=Local&parseTime=true", user, password, host, port, name) db, err := gorm.Open("mysql", connectString) if err != nil { @@ -41,6 +41,7 @@ func NewMySQLStorage(host, port, name, user, password string, maxConn, maxIdleCo } db.DB().SetMaxIdleConns(maxIdleConn) db.DB().SetMaxOpenConns(maxConn) + db.DB().SetConnMaxLifetime(time.Duration(connMaxLifetime) * time.Second) //db.LogMode(true) mySQLStorage := new(MySQLStorage) mySQLStorage.db = db diff --git a/engine/storage_postgres.go b/engine/storage_postgres.go index 4dbe81a65..20e1a06a7 100644 --- a/engine/storage_postgres.go +++ b/engine/storage_postgres.go @@ -19,14 +19,14 @@ package engine import ( "fmt" + "time" "github.com/cgrates/cgrates/utils" - "github.com/jinzhu/gorm" _ "github.com/lib/pq" ) -func NewPostgresStorage(host, port, name, user, password string, maxConn, maxIdleConn int) (*SQLStorage, error) { +func NewPostgresStorage(host, port, name, user, password string, maxConn, maxIdleConn, connMaxLifetime int) (*SQLStorage, error) { connectString := fmt.Sprintf("host=%s port=%s dbname=%s user=%s password=%s sslmode=disable", host, port, name, user, password) db, err := gorm.Open("postgres", connectString) if err != nil { @@ -38,6 +38,7 @@ func NewPostgresStorage(host, port, name, user, password string, maxConn, maxIdl } db.DB().SetMaxIdleConns(maxIdleConn) db.DB().SetMaxOpenConns(maxConn) + db.DB().SetConnMaxLifetime(time.Duration(connMaxLifetime) * time.Second) //db.LogMode(true) postgressStorage := new(PostgresStorage) postgressStorage.db = db diff --git a/engine/storage_redis.go b/engine/storage_redis.go index f735e872d..f9da8c933 100644 --- a/engine/storage_redis.go +++ b/engine/storage_redis.go @@ -1471,7 +1471,6 @@ func (rs *RedisStorage) GetTiming(id string, skipCache bool, transactionID strin } func (rs *RedisStorage) SetTiming(t *utils.TPTiming, transactionID string) error { - fmt.Println("Redis") result, err := rs.ms.Marshal(t) if err != nil { return err diff --git a/engine/storage_utils.go b/engine/storage_utils.go index 7ee9b9b87..c71d36bd9 100644 --- a/engine/storage_utils.go +++ b/engine/storage_utils.go @@ -55,7 +55,7 @@ func ConfigureDataStorage(db_type, host, port, name, user, pass, marshaler strin return d, nil } -func ConfigureStorStorage(db_type, host, port, name, user, pass, marshaler string, maxConn, maxIdleConn int, cdrsIndexes []string) (db Storage, err error) { +func ConfigureStorStorage(db_type, host, port, name, user, pass, marshaler string, maxConn, maxIdleConn, connMaxLifetime int, cdrsIndexes []string) (db Storage, err error) { var d Storage switch db_type { /* @@ -74,9 +74,9 @@ func ConfigureStorStorage(db_type, host, port, name, user, pass, marshaler strin case utils.MONGO: d, err = NewMongoStorage(host, port, name, user, pass, utils.StorDB, cdrsIndexes, nil, 1) case utils.POSTGRES: - d, err = NewPostgresStorage(host, port, name, user, pass, maxConn, maxIdleConn) + d, err = NewPostgresStorage(host, port, name, user, pass, maxConn, maxIdleConn, connMaxLifetime) case utils.MYSQL: - d, err = NewMySQLStorage(host, port, name, user, pass, maxConn, maxIdleConn) + d, err = NewMySQLStorage(host, port, name, user, pass, maxConn, maxIdleConn, connMaxLifetime) default: err = errors.New(fmt.Sprintf("Unknown db '%s' valid options are [%s, %s, %s]", db_type, utils.MYSQL, utils.MONGO, utils.POSTGRES)) @@ -87,13 +87,13 @@ func ConfigureStorStorage(db_type, host, port, name, user, pass, marshaler strin return d, nil } -func ConfigureLoadStorage(db_type, host, port, name, user, pass, marshaler string, maxConn, maxIdleConn int, cdrsIndexes []string) (db LoadStorage, err error) { +func ConfigureLoadStorage(db_type, host, port, name, user, pass, marshaler string, maxConn, maxIdleConn, connMaxLifetime int, cdrsIndexes []string) (db LoadStorage, err error) { var d LoadStorage switch db_type { case utils.POSTGRES: - d, err = NewPostgresStorage(host, port, name, user, pass, maxConn, maxIdleConn) + d, err = NewPostgresStorage(host, port, name, user, pass, maxConn, maxIdleConn, connMaxLifetime) case utils.MYSQL: - d, err = NewMySQLStorage(host, port, name, user, pass, maxConn, maxIdleConn) + d, err = NewMySQLStorage(host, port, name, user, pass, maxConn, maxIdleConn, connMaxLifetime) case utils.MONGO: d, err = NewMongoStorage(host, port, name, user, pass, utils.StorDB, cdrsIndexes, nil, 1) default: @@ -106,13 +106,13 @@ func ConfigureLoadStorage(db_type, host, port, name, user, pass, marshaler strin return d, nil } -func ConfigureCdrStorage(db_type, host, port, name, user, pass string, maxConn, maxIdleConn int, cdrsIndexes []string) (db CdrStorage, err error) { +func ConfigureCdrStorage(db_type, host, port, name, user, pass string, maxConn, maxIdleConn, connMaxLifetime int, cdrsIndexes []string) (db CdrStorage, err error) { var d CdrStorage switch db_type { case utils.POSTGRES: - d, err = NewPostgresStorage(host, port, name, user, pass, maxConn, maxIdleConn) + d, err = NewPostgresStorage(host, port, name, user, pass, maxConn, maxIdleConn, connMaxLifetime) case utils.MYSQL: - d, err = NewMySQLStorage(host, port, name, user, pass, maxConn, maxIdleConn) + d, err = NewMySQLStorage(host, port, name, user, pass, maxConn, maxIdleConn, connMaxLifetime) case utils.MONGO: d, err = NewMongoStorage(host, port, name, user, pass, utils.StorDB, cdrsIndexes, nil, 1) default: diff --git a/engine/stordb_it_test.go b/engine/stordb_it_test.go index 0b51f492c..d72734fa6 100644 --- a/engine/stordb_it_test.go +++ b/engine/stordb_it_test.go @@ -65,7 +65,7 @@ func TestStorDBitMySQL(t *testing.T) { t.Fatal(err) } if storDB, err = NewMySQLStorage(cfg.StorDBHost, cfg.StorDBPort, cfg.StorDBName, - cfg.StorDBUser, cfg.StorDBPass, cfg.StorDBMaxOpenConns, cfg.StorDBMaxIdleConns); err != nil { + cfg.StorDBUser, cfg.StorDBPass, cfg.StorDBMaxOpenConns, cfg.StorDBMaxIdleConns, cfg.StorDBConnMaxLifetime); err != nil { t.Fatal(err) } storDB2ndDBname = "mysql" @@ -82,7 +82,7 @@ func TestStorDBitPostgresSQL(t *testing.T) { t.Fatal(err) } if storDB, err = NewPostgresStorage(cfg.StorDBHost, cfg.StorDBPort, cfg.StorDBName, - cfg.StorDBUser, cfg.StorDBPass, cfg.StorDBMaxOpenConns, cfg.StorDBMaxIdleConns); err != nil { + cfg.StorDBUser, cfg.StorDBPass, cfg.StorDBMaxOpenConns, cfg.StorDBMaxIdleConns, cfg.StorDBConnMaxLifetime); err != nil { t.Fatal(err) } storDB2ndDBname = "postgres"