MM-28859 Add feature flag managment system using split.io and remove viper. (#15954)
* Add feature flag managment system using split.io and remove viper. * Fixing tests. * Attempt to fix postgres tests. * Fix watch filepath for advanced logging. * Review fixes. * Some error wrapping. * Remove unessisary store interface. * Desanitize SplitKey * Simplify. * Review feedback. * Rename split mlog adatper to split logger. * fsInner * Style. * Restore oldcfg test. * Downgrading non-actionable feature flag errors to warnings. Co-authored-by: Mattermod <mattermod@users.noreply.github.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
8bb772638c
Коммит
1aadd36644
@@ -6,7 +6,7 @@ package config
|
||||
import (
|
||||
"bytes"
|
||||
"database/sql"
|
||||
"io/ioutil"
|
||||
"encoding/json"
|
||||
"strings"
|
||||
|
||||
"github.com/jmoiron/sqlx"
|
||||
@@ -28,9 +28,8 @@ import (
|
||||
const MaxWriteLength = 4 * 1024 * 1024
|
||||
|
||||
// DatabaseStore is a config store backed by a database.
|
||||
// Not to be used directly. Only to be used as a backing store for config.Store
|
||||
type DatabaseStore struct {
|
||||
commonStore
|
||||
|
||||
originalDsn string
|
||||
driverName string
|
||||
dataSourceName string
|
||||
@@ -59,10 +58,6 @@ func NewDatabaseStore(dsn string) (ds *DatabaseStore, err error) {
|
||||
return nil, errors.Wrap(err, "failed to initialize")
|
||||
}
|
||||
|
||||
if err = ds.Load(); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to load")
|
||||
}
|
||||
|
||||
return ds, nil
|
||||
}
|
||||
|
||||
@@ -159,8 +154,8 @@ func parseDSN(dsn string) (string, string, error) {
|
||||
}
|
||||
|
||||
// Set replaces the current configuration in its entirety and updates the backing store.
|
||||
func (ds *DatabaseStore) Set(newCfg *model.Config) (*model.Config, error) {
|
||||
return ds.commonStore.set(newCfg, true, ds.commonStore.validate, ds.persist)
|
||||
func (ds *DatabaseStore) Set(newCfg *model.Config) error {
|
||||
return ds.persist(newCfg)
|
||||
}
|
||||
|
||||
// maxLength identifies the maximum length of a configuration or configuration file
|
||||
@@ -232,35 +227,23 @@ func (ds *DatabaseStore) persist(cfg *model.Config) error {
|
||||
}
|
||||
|
||||
// Load updates the current configuration from the backing store.
|
||||
func (ds *DatabaseStore) Load() (err error) {
|
||||
var needsSave bool
|
||||
func (ds *DatabaseStore) Load() ([]byte, error) {
|
||||
var configurationData []byte
|
||||
|
||||
row := ds.db.QueryRow("SELECT Value FROM Configurations WHERE Active")
|
||||
if err = row.Scan(&configurationData); err != nil && err != sql.ErrNoRows {
|
||||
return errors.Wrap(err, "failed to query active configuration")
|
||||
if err := row.Scan(&configurationData); err != nil && err != sql.ErrNoRows {
|
||||
return nil, errors.Wrap(err, "failed to query active configuration")
|
||||
}
|
||||
|
||||
// Initialize from the default config if no active configuration could be found.
|
||||
if len(configurationData) == 0 {
|
||||
needsSave = true
|
||||
|
||||
defaultCfg := &model.Config{}
|
||||
defaultCfg.SetDefaults()
|
||||
|
||||
// Assume the database storing the config is also to be used for the application.
|
||||
// This can be overridden using environment variables on first start if necessary,
|
||||
// or changed from the system console afterwards.
|
||||
*defaultCfg.SqlSettings.DriverName = ds.driverName
|
||||
*defaultCfg.SqlSettings.DataSource = ds.dataSourceName
|
||||
|
||||
configurationData, err = marshalConfig(defaultCfg)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to serialize default config")
|
||||
}
|
||||
configWithDB := model.Config{}
|
||||
configWithDB.SqlSettings.DriverName = model.NewString(ds.driverName)
|
||||
configWithDB.SqlSettings.DataSource = model.NewString(ds.dataSourceName)
|
||||
return json.Marshal(configWithDB)
|
||||
}
|
||||
|
||||
return ds.commonStore.load(ioutil.NopCloser(bytes.NewReader(configurationData)), needsSave, ds.commonStore.validate, ds.persist)
|
||||
return configurationData, nil
|
||||
}
|
||||
|
||||
// GetFile fetches the contents of a previously persisted configuration file.
|
||||
@@ -287,7 +270,6 @@ func (ds *DatabaseStore) SetFile(name string, data []byte) error {
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "file data failed length check")
|
||||
}
|
||||
|
||||
params := map[string]interface{}{
|
||||
"name": name,
|
||||
"data": data,
|
||||
@@ -352,8 +334,10 @@ func (ds *DatabaseStore) String() string {
|
||||
|
||||
// Close cleans up resources associated with the store.
|
||||
func (ds *DatabaseStore) Close() error {
|
||||
ds.configLock.Lock()
|
||||
defer ds.configLock.Unlock()
|
||||
|
||||
return ds.db.Close()
|
||||
}
|
||||
|
||||
// Watch nothing on memory store
|
||||
func (ds *DatabaseStore) Watch(_ func()) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
Ссылка в новой задаче
Block a user