summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/diagnostics.go15
-rw-r--r--config/default.json1
-rw-r--r--i18n/en.json58
-rw-r--r--model/config.go27
-rw-r--r--store/sqlstore/supplier.go3
-rw-r--r--store/sqlstore/supplier_test.go32
-rw-r--r--store/storetest/docker.go20
7 files changed, 88 insertions, 68 deletions
diff --git a/app/diagnostics.go b/app/diagnostics.go
index 3df62c41d..e9b3405be 100644
--- a/app/diagnostics.go
+++ b/app/diagnostics.go
@@ -297,13 +297,14 @@ func (a *App) trackConfig() {
})
a.SendDiagnostic(TRACK_CONFIG_SQL, map[string]interface{}{
- "driver_name": *cfg.SqlSettings.DriverName,
- "trace": cfg.SqlSettings.Trace,
- "max_idle_conns": *cfg.SqlSettings.MaxIdleConns,
- "max_open_conns": *cfg.SqlSettings.MaxOpenConns,
- "data_source_replicas": len(cfg.SqlSettings.DataSourceReplicas),
- "data_source_search_replicas": len(cfg.SqlSettings.DataSourceSearchReplicas),
- "query_timeout": *cfg.SqlSettings.QueryTimeout,
+ "driver_name": *cfg.SqlSettings.DriverName,
+ "trace": cfg.SqlSettings.Trace,
+ "max_idle_conns": *cfg.SqlSettings.MaxIdleConns,
+ "conn_max_lifetime_milliseconds": *cfg.SqlSettings.ConnMaxLifetimeMilliseconds,
+ "max_open_conns": *cfg.SqlSettings.MaxOpenConns,
+ "data_source_replicas": len(cfg.SqlSettings.DataSourceReplicas),
+ "data_source_search_replicas": len(cfg.SqlSettings.DataSourceSearchReplicas),
+ "query_timeout": *cfg.SqlSettings.QueryTimeout,
})
a.SendDiagnostic(TRACK_CONFIG_LOG, map[string]interface{}{
diff --git a/config/default.json b/config/default.json
index 2d1e6ceec..6e4f6d1eb 100644
--- a/config/default.json
+++ b/config/default.json
@@ -119,6 +119,7 @@
"DataSourceReplicas": [],
"DataSourceSearchReplicas": [],
"MaxIdleConns": 20,
+ "ConnMaxLifetimeMilliseconds": 3600000,
"MaxOpenConns": 300,
"Trace": false,
"AtRestEncryptKey": "",
diff --git a/i18n/en.json b/i18n/en.json
index 6c7b44443..fd9888e39 100644
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -3064,11 +3064,11 @@
},
{
"id": "ent.cluster.config_changed.info",
- "translation": "Cluster configuration has changed for id={{ .id }}. The cluster may become unstable and a restart is required. To ensure the cluster is configured correctly you should perform a rolling restart immediately."
+ "translation": "Cluster configuration has changed for id={{ .id }}. The cluster may become unstable and a restart is required. To ensure the cluster is configured correctly you should perform a rolling restart immediately."
},
{
"id": "ent.cluster.save_config.error",
- "translation": "System Console is set to read-only when High Availability is enabled unless ReadOnlyConfig is disabled in the configuration file."
+ "translation": "System Console is set to read-only when High Availability is enabled unless ReadOnlyConfig is disabled in the configuration file."
},
{
"id": "ent.compliance.bad_export_type.appError",
@@ -3812,11 +3812,11 @@
},
{
"id": "model.config.is_valid.email_batching_buffer_size.app_error",
- "translation": "Invalid email batching buffer size for email settings. Must be zero or a positive number."
+ "translation": "Invalid email batching buffer size for email settings. Must be zero or a positive number."
},
{
"id": "model.config.is_valid.email_batching_interval.app_error",
- "translation": "Invalid email batching interval for email settings. Must be 30 seconds or more."
+ "translation": "Invalid email batching interval for email settings. Must be 30 seconds or more."
},
{
"id": "model.config.is_valid.email_notification_contents_type.app_error",
@@ -3824,23 +3824,23 @@
},
{
"id": "model.config.is_valid.email_salt.app_error",
- "translation": "Invalid invite salt for email settings. Must be 32 chars or more."
+ "translation": "Invalid invite salt for email settings. Must be 32 chars or more."
},
{
"id": "model.config.is_valid.email_security.app_error",
- "translation": "Invalid connection security for email settings. Must be '', 'TLS', or 'STARTTLS'"
+ "translation": "Invalid connection security for email settings. Must be '', 'TLS', or 'STARTTLS'"
},
{
"id": "model.config.is_valid.encrypt_sql.app_error",
- "translation": "Invalid at rest encrypt key for SQL settings. Must be 32 chars or more."
+ "translation": "Invalid at rest encrypt key for SQL settings. Must be 32 chars or more."
},
{
"id": "model.config.is_valid.file_driver.app_error",
- "translation": "Invalid driver name for file settings. Must be 'local' or 'amazons3'"
+ "translation": "Invalid driver name for file settings. Must be 'local' or 'amazons3'"
},
{
"id": "model.config.is_valid.file_salt.app_error",
- "translation": "Invalid public link salt for file settings. Must be 32 chars or more."
+ "translation": "Invalid public link salt for file settings. Must be 32 chars or more."
},
{
"id": "model.config.is_valid.group_unread_channels.app_error",
@@ -3872,7 +3872,7 @@
},
{
"id": "model.config.is_valid.ldap_security.app_error",
- "translation": "Invalid connection security for AD/LDAP settings. Must be '', 'TLS', or 'STARTTLS'"
+ "translation": "Invalid connection security for AD/LDAP settings. Must be '', 'TLS', or 'STARTTLS'"
},
{
"id": "model.config.is_valid.ldap_server",
@@ -3896,7 +3896,7 @@
},
{
"id": "model.config.is_valid.login_attempts.app_error",
- "translation": "Invalid maximum login attempts for service settings. Must be a positive number."
+ "translation": "Invalid maximum login attempts for service settings. Must be a positive number."
},
{
"id": "model.config.is_valid.max_burst.app_error",
@@ -3904,7 +3904,7 @@
},
{
"id": "model.config.is_valid.max_channels.app_error",
- "translation": "Invalid maximum channels per team for team settings. Must be a positive number."
+ "translation": "Invalid maximum channels per team for team settings. Must be a positive number."
},
{
"id": "model.config.is_valid.max_file_size.app_error",
@@ -3912,11 +3912,11 @@
},
{
"id": "model.config.is_valid.max_notify_per_channel.app_error",
- "translation": "Invalid maximum notifications per channel for team settings. Must be a positive number."
+ "translation": "Invalid maximum notifications per channel for team settings. Must be a positive number."
},
{
"id": "model.config.is_valid.max_users.app_error",
- "translation": "Invalid maximum users per team for team settings. Must be a positive number."
+ "translation": "Invalid maximum users per team for team settings. Must be a positive number."
},
{
"id": "model.config.is_valid.message_export.batch_size.app_error",
@@ -3964,11 +3964,11 @@
},
{
"id": "model.config.is_valid.rate_mem.app_error",
- "translation": "Invalid memory store size for rate limit settings. Must be a positive number"
+ "translation": "Invalid memory store size for rate limit settings. Must be a positive number"
},
{
"id": "model.config.is_valid.rate_sec.app_error",
- "translation": "Invalid per sec for rate limit settings. Must be a positive number"
+ "translation": "Invalid per sec for rate limit settings. Must be a positive number"
},
{
"id": "model.config.is_valid.read_timeout.app_error",
@@ -3976,7 +3976,7 @@
},
{
"id": "model.config.is_valid.restrict_direct_message.app_error",
- "translation": "Invalid direct message restriction. Must be 'any', or 'team'"
+ "translation": "Invalid direct message restriction. Must be 'any', or 'team'"
},
{
"id": "model.config.is_valid.saml_assertion_consumer_service_url.app_error",
@@ -4024,27 +4024,31 @@
},
{
"id": "model.config.is_valid.sql_data_src.app_error",
- "translation": "Invalid data source for SQL settings. Must be set."
+ "translation": "Invalid data source for SQL settings. Must be set."
},
{
"id": "model.config.is_valid.sql_driver.app_error",
- "translation": "Invalid driver name for SQL settings. Must be 'mysql' or 'postgres'"
+ "translation": "Invalid driver name for SQL settings. Must be 'mysql' or 'postgres'"
},
{
"id": "model.config.is_valid.sql_idle.app_error",
- "translation": "Invalid maximum idle connection for SQL settings. Must be a positive number."
+ "translation": "Invalid maximum idle connection for SQL settings. Must be a positive number."
},
{
"id": "model.config.is_valid.sql_max_conn.app_error",
- "translation": "Invalid maximum open connection for SQL settings. Must be a positive number."
+ "translation": "Invalid maximum open connection for SQL settings. Must be a positive number."
+ },
+ {
+ "id": "model.config.is_valid.sql_conn_max_lifetime_milliseconds.app_error",
+ "translation": "Invalid connection maximum lifetime for SQL settings. Must be a non-negative number."
},
{
"id": "model.config.is_valid.sql_query_timeout.app_error",
- "translation": "Invalid query timeout for SQL settings. Must be a positive number."
+ "translation": "Invalid query timeout for SQL settings. Must be a positive number."
},
{
"id": "model.config.is_valid.teammate_name_display.app_error",
- "translation": "Invalid teammate display. Must be 'full_name', 'nickname_full_name' or 'username'"
+ "translation": "Invalid teammate display. Must be 'full_name', 'nickname_full_name' or 'username'"
},
{
"id": "model.config.is_valid.time_between_user_typing.app_error",
@@ -6040,7 +6044,7 @@
},
{
"id": "utils.config.add_client_locale.app_error",
- "translation": "Unable to load mattermost configuration file: Adding DefaultClientLocale to AvailableLocales."
+ "translation": "Unable to load mattermost configuration file: Adding DefaultClientLocale to AvailableLocales."
},
{
"id": "utils.config.load_config.decoding.panic",
@@ -6056,15 +6060,15 @@
},
{
"id": "utils.config.supported_available_locales.app_error",
- "translation": "Unable to load mattermost configuration file: AvailableLocales must include DefaultClientLocale. Setting AvailableLocales to all locales as default value."
+ "translation": "Unable to load mattermost configuration file: AvailableLocales must include DefaultClientLocale. Setting AvailableLocales to all locales as default value."
},
{
"id": "utils.config.supported_client_locale.app_error",
- "translation": "Unable to load mattermost configuration file: DefaultClientLocale must be one of the supported locales. Setting DefaultClientLocale to en as default value."
+ "translation": "Unable to load mattermost configuration file: DefaultClientLocale must be one of the supported locales. Setting DefaultClientLocale to en as default value."
},
{
"id": "utils.config.supported_server_locale.app_error",
- "translation": "Unable to load mattermost configuration file: DefaultServerLocale must be one of the supported locales. Setting DefaultServerLocale to en as default value."
+ "translation": "Unable to load mattermost configuration file: DefaultServerLocale must be one of the supported locales. Setting DefaultServerLocale to en as default value."
},
{
"id": "utils.file.list_directory.local.app_error",
diff --git a/model/config.go b/model/config.go
index ce66f2f05..e6bd04dfc 100644
--- a/model/config.go
+++ b/model/config.go
@@ -605,15 +605,16 @@ type SSOSettings struct {
}
type SqlSettings struct {
- DriverName *string
- DataSource *string
- DataSourceReplicas []string
- DataSourceSearchReplicas []string
- MaxIdleConns *int
- MaxOpenConns *int
- Trace bool
- AtRestEncryptKey string
- QueryTimeout *int
+ DriverName *string
+ DataSource *string
+ DataSourceReplicas []string
+ DataSourceSearchReplicas []string
+ MaxIdleConns *int
+ ConnMaxLifetimeMilliseconds *int
+ MaxOpenConns *int
+ Trace bool
+ AtRestEncryptKey string
+ QueryTimeout *int
}
func (s *SqlSettings) SetDefaults() {
@@ -637,6 +638,10 @@ func (s *SqlSettings) SetDefaults() {
s.MaxOpenConns = NewInt(300)
}
+ if s.ConnMaxLifetimeMilliseconds == nil {
+ s.ConnMaxLifetimeMilliseconds = NewInt(3600000)
+ }
+
if s.QueryTimeout == nil {
s.QueryTimeout = NewInt(30)
}
@@ -2069,6 +2074,10 @@ func (ss *SqlSettings) isValid() *AppError {
return NewAppError("Config.IsValid", "model.config.is_valid.sql_idle.app_error", nil, "", http.StatusBadRequest)
}
+ if *ss.ConnMaxLifetimeMilliseconds < 0 {
+ return NewAppError("Config.IsValid", "model.config.is_valid.sql_conn_max_lifetime_milliseconds.app_error", nil, "", http.StatusBadRequest)
+ }
+
if *ss.QueryTimeout <= 0 {
return NewAppError("Config.IsValid", "model.config.is_valid.sql_query_timeout.app_error", nil, "", http.StatusBadRequest)
}
diff --git a/store/sqlstore/supplier.go b/store/sqlstore/supplier.go
index 1e6bdcba1..6c49d91fb 100644
--- a/store/sqlstore/supplier.go
+++ b/store/sqlstore/supplier.go
@@ -28,7 +28,6 @@ import (
const (
INDEX_TYPE_FULL_TEXT = "full_text"
INDEX_TYPE_DEFAULT = "default"
- MAX_DB_CONN_LIFETIME = 60
DB_PING_ATTEMPTS = 18
DB_PING_TIMEOUT_SECS = 10
)
@@ -218,7 +217,7 @@ func setupConnection(con_type string, dataSource string, settings *model.SqlSett
db.SetMaxIdleConns(*settings.MaxIdleConns)
db.SetMaxOpenConns(*settings.MaxOpenConns)
- db.SetConnMaxLifetime(time.Duration(MAX_DB_CONN_LIFETIME) * time.Minute)
+ db.SetConnMaxLifetime(time.Duration(*settings.ConnMaxLifetimeMilliseconds) * time.Millisecond)
var dbmap *gorp.DbMap
diff --git a/store/sqlstore/supplier_test.go b/store/sqlstore/supplier_test.go
index 5aacfbe6a..3835bd01f 100644
--- a/store/sqlstore/supplier_test.go
+++ b/store/sqlstore/supplier_test.go
@@ -73,17 +73,19 @@ func TestGetReplica(t *testing.T) {
driverName := model.DATABASE_DRIVER_SQLITE
dataSource := ":memory:"
maxIdleConns := 1
+ connMaxLifetimeMilliseconds := 3600000
maxOpenConns := 1
queryTimeout := 5
settings := model.SqlSettings{
- DriverName: &driverName,
- DataSource: &dataSource,
- MaxIdleConns: &maxIdleConns,
- MaxOpenConns: &maxOpenConns,
- QueryTimeout: &queryTimeout,
- DataSourceReplicas: testCase.DataSourceReplicas,
- DataSourceSearchReplicas: testCase.DataSourceSearchReplicas,
+ DriverName: &driverName,
+ DataSource: &dataSource,
+ MaxIdleConns: &maxIdleConns,
+ ConnMaxLifetimeMilliseconds: &connMaxLifetimeMilliseconds,
+ MaxOpenConns: &maxOpenConns,
+ QueryTimeout: &queryTimeout,
+ DataSourceReplicas: testCase.DataSourceReplicas,
+ DataSourceSearchReplicas: testCase.DataSourceSearchReplicas,
}
supplier := sqlstore.NewSqlSupplier(settings, nil)
@@ -209,17 +211,19 @@ func TestGetAllConns(t *testing.T) {
driverName := model.DATABASE_DRIVER_SQLITE
dataSource := ":memory:"
maxIdleConns := 1
+ connMaxLifetimeMilliseconds := 3600000
maxOpenConns := 1
queryTimeout := 5
settings := model.SqlSettings{
- DriverName: &driverName,
- DataSource: &dataSource,
- MaxIdleConns: &maxIdleConns,
- MaxOpenConns: &maxOpenConns,
- QueryTimeout: &queryTimeout,
- DataSourceReplicas: testCase.DataSourceReplicas,
- DataSourceSearchReplicas: testCase.DataSourceSearchReplicas,
+ DriverName: &driverName,
+ DataSource: &dataSource,
+ MaxIdleConns: &maxIdleConns,
+ ConnMaxLifetimeMilliseconds: &connMaxLifetimeMilliseconds,
+ MaxOpenConns: &maxOpenConns,
+ QueryTimeout: &queryTimeout,
+ DataSourceReplicas: testCase.DataSourceReplicas,
+ DataSourceSearchReplicas: testCase.DataSourceSearchReplicas,
}
supplier := sqlstore.NewSqlSupplier(settings, nil)
diff --git a/store/storetest/docker.go b/store/storetest/docker.go
index f3830a6fe..f5b8807d0 100644
--- a/store/storetest/docker.go
+++ b/store/storetest/docker.go
@@ -76,17 +76,19 @@ func NewPostgreSQLContainer() (*RunningContainer, *model.SqlSettings, error) {
func databaseSettings(driver, dataSource string) *model.SqlSettings {
settings := &model.SqlSettings{
- DriverName: &driver,
- DataSource: &dataSource,
- DataSourceReplicas: []string{},
- DataSourceSearchReplicas: []string{},
- MaxIdleConns: new(int),
- MaxOpenConns: new(int),
- Trace: false,
- AtRestEncryptKey: model.NewRandomString(32),
- QueryTimeout: new(int),
+ DriverName: &driver,
+ DataSource: &dataSource,
+ DataSourceReplicas: []string{},
+ DataSourceSearchReplicas: []string{},
+ MaxIdleConns: new(int),
+ ConnMaxLifetimeMilliseconds: new(int),
+ MaxOpenConns: new(int),
+ Trace: false,
+ AtRestEncryptKey: model.NewRandomString(32),
+ QueryTimeout: new(int),
}
*settings.MaxIdleConns = 10
+ *settings.ConnMaxLifetimeMilliseconds = 3600000
*settings.MaxOpenConns = 100
*settings.QueryTimeout = 10
return settings