2014-08-07 12:49:48 +04:00
|
|
|
package config
|
|
|
|
|
|
|
|
import (
|
2014-10-08 12:02:00 +04:00
|
|
|
"bytes"
|
2014-10-08 12:20:09 +04:00
|
|
|
"errors"
|
2014-10-08 12:02:00 +04:00
|
|
|
"io"
|
2014-08-07 12:49:48 +04:00
|
|
|
"io/ioutil"
|
2014-11-01 18:28:28 +03:00
|
|
|
"sync"
|
2015-05-04 17:42:28 +03:00
|
|
|
|
2017-06-08 18:01:11 +03:00
|
|
|
"fmt"
|
2017-07-31 04:51:35 +03:00
|
|
|
|
2017-06-08 18:01:11 +03:00
|
|
|
"github.com/pelletier/go-toml"
|
2015-05-04 17:42:28 +03:00
|
|
|
"github.com/siddontang/go/ioutil2"
|
2014-08-07 12:49:48 +04:00
|
|
|
)
|
|
|
|
|
2014-10-08 12:20:09 +04:00
|
|
|
var (
|
|
|
|
ErrNoConfigFile = errors.New("Running without a config file")
|
|
|
|
)
|
2014-08-07 12:49:48 +04:00
|
|
|
|
|
|
|
const (
|
2014-10-11 12:00:59 +04:00
|
|
|
DefaultAddr string = "127.0.0.1:6380"
|
2014-08-07 12:49:48 +04:00
|
|
|
|
|
|
|
DefaultDBName string = "goleveldb"
|
|
|
|
|
|
|
|
DefaultDataDir string = "./var"
|
2014-10-24 09:01:13 +04:00
|
|
|
|
|
|
|
KB int = 1024
|
|
|
|
MB int = KB * 1024
|
|
|
|
GB int = MB * 1024
|
2014-08-07 12:49:48 +04:00
|
|
|
)
|
|
|
|
|
|
|
|
type LevelDBConfig struct {
|
2014-08-27 11:37:42 +04:00
|
|
|
Compression bool `toml:"compression"`
|
|
|
|
BlockSize int `toml:"block_size"`
|
|
|
|
WriteBufferSize int `toml:"write_buffer_size"`
|
|
|
|
CacheSize int `toml:"cache_size"`
|
|
|
|
MaxOpenFiles int `toml:"max_open_files"`
|
2017-11-27 03:51:18 +03:00
|
|
|
MaxFileSize int `toml:"max_file_size"`
|
2014-08-07 12:49:48 +04:00
|
|
|
}
|
|
|
|
|
2014-10-24 09:01:13 +04:00
|
|
|
type RocksDBConfig struct {
|
|
|
|
Compression int `toml:"compression"`
|
|
|
|
BlockSize int `toml:"block_size"`
|
|
|
|
WriteBufferSize int `toml:"write_buffer_size"`
|
|
|
|
CacheSize int `toml:"cache_size"`
|
|
|
|
MaxOpenFiles int `toml:"max_open_files"`
|
|
|
|
MaxWriteBufferNum int `toml:"max_write_buffer_num"`
|
|
|
|
MinWriteBufferNumberToMerge int `toml:"min_write_buffer_number_to_merge"`
|
|
|
|
NumLevels int `toml:"num_levels"`
|
|
|
|
Level0FileNumCompactionTrigger int `toml:"level0_file_num_compaction_trigger"`
|
|
|
|
Level0SlowdownWritesTrigger int `toml:"level0_slowdown_writes_trigger"`
|
|
|
|
Level0StopWritesTrigger int `toml:"level0_stop_writes_trigger"`
|
|
|
|
TargetFileSizeBase int `toml:"target_file_size_base"`
|
|
|
|
TargetFileSizeMultiplier int `toml:"target_file_size_multiplier"`
|
|
|
|
MaxBytesForLevelBase int `toml:"max_bytes_for_level_base"`
|
|
|
|
MaxBytesForLevelMultiplier int `toml:"max_bytes_for_level_multiplier"`
|
|
|
|
DisableAutoCompactions bool `toml:"disable_auto_compactions"`
|
|
|
|
UseFsync bool `toml:"use_fsync"`
|
|
|
|
MaxBackgroundCompactions int `toml:"max_background_compactions"`
|
|
|
|
MaxBackgroundFlushes int `toml:"max_background_flushes"`
|
|
|
|
EnableStatistics bool `toml:"enable_statistics"`
|
|
|
|
StatsDumpPeriodSec int `toml:"stats_dump_period_sec"`
|
|
|
|
BackgroundThreads int `toml:"background_theads"`
|
|
|
|
HighPriorityBackgroundThreads int `toml:"high_priority_background_threads"`
|
2014-10-24 19:30:27 +04:00
|
|
|
DisableWAL bool `toml:"disable_wal"`
|
2017-07-31 04:51:35 +03:00
|
|
|
MaxManifestFileSize int `toml:"max_manifest_file_size"`
|
2014-10-24 09:01:13 +04:00
|
|
|
}
|
|
|
|
|
2014-08-07 12:49:48 +04:00
|
|
|
type LMDBConfig struct {
|
2014-08-27 11:37:42 +04:00
|
|
|
MapSize int `toml:"map_size"`
|
|
|
|
NoSync bool `toml:"nosync"`
|
2014-08-07 12:49:48 +04:00
|
|
|
}
|
|
|
|
|
2014-09-22 13:50:51 +04:00
|
|
|
type ReplicationConfig struct {
|
2014-10-05 13:24:44 +04:00
|
|
|
Path string `toml:"path"`
|
|
|
|
Sync bool `toml:"sync"`
|
|
|
|
WaitSyncTime int `toml:"wait_sync_time"`
|
|
|
|
WaitMaxSlaveAcks int `toml:"wait_max_slave_acks"`
|
2014-10-09 11:05:15 +04:00
|
|
|
ExpiredLogDays int `toml:"expired_log_days"`
|
2014-11-07 11:35:54 +03:00
|
|
|
StoreName string `toml:"store_name"`
|
|
|
|
MaxLogFileSize int64 `toml:"max_log_file_size"`
|
2014-11-15 16:20:12 +03:00
|
|
|
MaxLogFileNum int `toml:"max_log_file_num"`
|
2014-10-09 11:05:15 +04:00
|
|
|
SyncLog int `toml:"sync_log"`
|
2014-10-05 13:24:44 +04:00
|
|
|
Compression bool `toml:"compression"`
|
2014-11-20 17:28:08 +03:00
|
|
|
UseMmap bool `toml:"use_mmap"`
|
2018-03-28 12:50:05 +03:00
|
|
|
MasterPassword string `toml:"master_password"`
|
2014-08-07 12:49:48 +04:00
|
|
|
}
|
|
|
|
|
2014-10-10 13:57:18 +04:00
|
|
|
type SnapshotConfig struct {
|
|
|
|
Path string `toml:"path"`
|
|
|
|
MaxNum int `toml:"max_num"`
|
|
|
|
}
|
|
|
|
|
2017-06-12 03:05:42 +03:00
|
|
|
type TLS struct {
|
|
|
|
Enabled bool `toml:"enabled"`
|
|
|
|
Certificate string `toml:"certificate"`
|
|
|
|
Key string `toml:"key"`
|
|
|
|
}
|
|
|
|
|
2017-06-08 18:01:11 +03:00
|
|
|
type AuthMethod func(c *Config, password string) bool
|
|
|
|
|
2014-08-07 12:49:48 +04:00
|
|
|
type Config struct {
|
2014-11-01 18:28:28 +03:00
|
|
|
m sync.RWMutex `toml:"-"`
|
|
|
|
|
2015-09-13 03:47:10 +03:00
|
|
|
AuthPassword string `toml:"auth_password"`
|
|
|
|
|
2017-06-08 18:01:11 +03:00
|
|
|
//AuthMethod custom authentication method
|
|
|
|
AuthMethod AuthMethod `toml:"-"`
|
|
|
|
|
2014-10-08 12:20:09 +04:00
|
|
|
FileName string `toml:"-"`
|
|
|
|
|
2017-04-16 05:37:47 +03:00
|
|
|
// Addr can be empty to assign a local address dynamically
|
2014-08-27 11:37:42 +04:00
|
|
|
Addr string `toml:"addr"`
|
2014-08-07 12:49:48 +04:00
|
|
|
|
2015-11-23 20:30:30 +03:00
|
|
|
AddrUnixSocketPerm string `toml:"addr_unixsocketperm"`
|
|
|
|
|
2014-08-27 11:37:42 +04:00
|
|
|
HttpAddr string `toml:"http_addr"`
|
2014-08-07 12:49:48 +04:00
|
|
|
|
2014-09-22 13:50:51 +04:00
|
|
|
SlaveOf string `toml:"slaveof"`
|
|
|
|
|
2019-02-02 16:41:19 +03:00
|
|
|
Readonly bool `toml:"readonly"`
|
2014-10-10 05:49:16 +04:00
|
|
|
|
2014-08-27 11:37:42 +04:00
|
|
|
DataDir string `toml:"data_dir"`
|
2014-08-07 12:49:48 +04:00
|
|
|
|
2015-03-04 12:46:40 +03:00
|
|
|
Databases int `toml:"databases"`
|
2015-03-04 04:15:28 +03:00
|
|
|
|
2014-10-16 05:35:35 +04:00
|
|
|
DBName string `toml:"db_name"`
|
|
|
|
DBPath string `toml:"db_path"`
|
|
|
|
DBSyncCommit int `toml:"db_sync_commit"`
|
2014-09-18 18:30:33 +04:00
|
|
|
|
2014-08-27 11:37:42 +04:00
|
|
|
LevelDB LevelDBConfig `toml:"leveldb"`
|
2014-10-24 09:01:13 +04:00
|
|
|
RocksDB RocksDBConfig `toml:"rocksdb"`
|
2014-08-07 12:49:48 +04:00
|
|
|
|
2014-08-27 11:37:42 +04:00
|
|
|
LMDB LMDBConfig `toml:"lmdb"`
|
2014-08-07 12:49:48 +04:00
|
|
|
|
2014-08-27 11:37:42 +04:00
|
|
|
AccessLog string `toml:"access_log"`
|
2014-09-22 13:50:51 +04:00
|
|
|
|
2014-09-23 13:28:09 +04:00
|
|
|
UseReplication bool `toml:"use_replication"`
|
|
|
|
Replication ReplicationConfig `toml:"replication"`
|
2014-10-10 13:57:18 +04:00
|
|
|
|
|
|
|
Snapshot SnapshotConfig `toml:"snapshot"`
|
2014-10-25 10:48:52 +04:00
|
|
|
|
2014-10-30 06:11:45 +03:00
|
|
|
ConnReadBufferSize int `toml:"conn_read_buffer_size"`
|
|
|
|
ConnWriteBufferSize int `toml:"conn_write_buffer_size"`
|
2014-10-31 15:33:32 +03:00
|
|
|
ConnKeepaliveInterval int `toml:"conn_keepalive_interval"`
|
2014-10-29 11:02:46 +03:00
|
|
|
|
|
|
|
TTLCheckInterval int `toml:"ttl_check_interval"`
|
2017-06-12 03:05:42 +03:00
|
|
|
|
|
|
|
//tls config
|
|
|
|
TLS TLS `toml:"tls"`
|
2014-08-07 12:49:48 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
func NewConfigWithFile(fileName string) (*Config, error) {
|
|
|
|
data, err := ioutil.ReadFile(fileName)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2017-04-16 05:37:47 +03:00
|
|
|
cfg, err := NewConfigWithData(data)
|
|
|
|
if err != nil {
|
2014-10-08 12:20:09 +04:00
|
|
|
return nil, err
|
|
|
|
}
|
2017-04-16 05:37:47 +03:00
|
|
|
|
|
|
|
cfg.FileName = fileName
|
|
|
|
return cfg, nil
|
2014-08-07 12:49:48 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
func NewConfigWithData(data []byte) (*Config, error) {
|
|
|
|
cfg := NewConfigDefault()
|
|
|
|
|
2017-06-08 18:01:11 +03:00
|
|
|
if err := toml.Unmarshal(data, cfg); err != nil {
|
|
|
|
return nil, fmt.Errorf("newConfigwithData: unmarashal: %s", err)
|
2014-08-07 12:49:48 +04:00
|
|
|
}
|
|
|
|
|
2014-10-11 12:00:59 +04:00
|
|
|
cfg.adjust()
|
|
|
|
|
2014-08-07 12:49:48 +04:00
|
|
|
return cfg, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewConfigDefault() *Config {
|
|
|
|
cfg := new(Config)
|
|
|
|
|
|
|
|
cfg.Addr = DefaultAddr
|
2014-10-11 12:00:59 +04:00
|
|
|
cfg.HttpAddr = ""
|
2014-08-07 12:49:48 +04:00
|
|
|
|
|
|
|
cfg.DataDir = DefaultDataDir
|
|
|
|
|
|
|
|
cfg.DBName = DefaultDBName
|
|
|
|
|
|
|
|
cfg.SlaveOf = ""
|
2014-10-10 05:49:16 +04:00
|
|
|
cfg.Readonly = false
|
2014-08-07 12:49:48 +04:00
|
|
|
|
2015-09-13 05:35:08 +03:00
|
|
|
// Disable Auth by default, by setting password to blank
|
2015-09-13 03:47:10 +03:00
|
|
|
cfg.AuthPassword = ""
|
|
|
|
|
2015-03-04 04:15:28 +03:00
|
|
|
// default databases number
|
|
|
|
cfg.Databases = 16
|
|
|
|
|
2014-08-07 12:49:48 +04:00
|
|
|
// disable access log
|
|
|
|
cfg.AccessLog = ""
|
|
|
|
|
2014-10-24 09:01:13 +04:00
|
|
|
cfg.LMDB.MapSize = 20 * MB
|
2014-08-25 10:18:23 +04:00
|
|
|
cfg.LMDB.NoSync = true
|
|
|
|
|
2014-10-11 12:00:59 +04:00
|
|
|
cfg.UseReplication = false
|
|
|
|
cfg.Replication.WaitSyncTime = 500
|
2014-09-27 05:10:08 +04:00
|
|
|
cfg.Replication.Compression = true
|
2014-10-05 13:24:44 +04:00
|
|
|
cfg.Replication.WaitMaxSlaveAcks = 2
|
2014-10-11 12:00:59 +04:00
|
|
|
cfg.Replication.SyncLog = 0
|
2014-11-20 17:28:08 +03:00
|
|
|
cfg.Replication.UseMmap = true
|
2014-10-11 13:44:31 +04:00
|
|
|
cfg.Snapshot.MaxNum = 1
|
2014-10-11 12:00:59 +04:00
|
|
|
|
2014-10-24 09:01:13 +04:00
|
|
|
cfg.RocksDB.EnableStatistics = false
|
|
|
|
cfg.RocksDB.UseFsync = false
|
|
|
|
cfg.RocksDB.DisableAutoCompactions = false
|
2014-10-24 19:30:27 +04:00
|
|
|
cfg.RocksDB.DisableWAL = false
|
2014-10-24 09:01:13 +04:00
|
|
|
|
2014-10-11 12:00:59 +04:00
|
|
|
cfg.adjust()
|
2014-09-23 13:28:09 +04:00
|
|
|
|
2014-08-07 12:49:48 +04:00
|
|
|
return cfg
|
|
|
|
}
|
|
|
|
|
2014-10-24 09:01:13 +04:00
|
|
|
func getDefault(d int, s int) int {
|
|
|
|
if s <= 0 {
|
|
|
|
return d
|
2014-10-11 12:00:59 +04:00
|
|
|
}
|
2017-04-16 05:37:47 +03:00
|
|
|
|
|
|
|
return s
|
2014-10-24 09:01:13 +04:00
|
|
|
}
|
2014-10-11 12:00:59 +04:00
|
|
|
|
2014-10-24 09:01:13 +04:00
|
|
|
func (cfg *Config) adjust() {
|
|
|
|
cfg.LevelDB.adjust()
|
2014-08-07 12:49:48 +04:00
|
|
|
|
2014-10-24 09:01:13 +04:00
|
|
|
cfg.RocksDB.adjust()
|
2014-08-07 12:49:48 +04:00
|
|
|
|
2014-10-24 09:01:13 +04:00
|
|
|
cfg.Replication.ExpiredLogDays = getDefault(7, cfg.Replication.ExpiredLogDays)
|
2014-11-20 12:33:38 +03:00
|
|
|
cfg.Replication.MaxLogFileNum = getDefault(50, cfg.Replication.MaxLogFileNum)
|
2014-10-25 10:48:52 +04:00
|
|
|
cfg.ConnReadBufferSize = getDefault(4*KB, cfg.ConnReadBufferSize)
|
|
|
|
cfg.ConnWriteBufferSize = getDefault(4*KB, cfg.ConnWriteBufferSize)
|
2014-10-29 11:02:46 +03:00
|
|
|
cfg.TTLCheckInterval = getDefault(1, cfg.TTLCheckInterval)
|
2015-03-15 06:39:31 +03:00
|
|
|
cfg.Databases = getDefault(16, cfg.Databases)
|
2014-10-24 09:01:13 +04:00
|
|
|
}
|
2014-08-07 12:49:48 +04:00
|
|
|
|
2014-10-24 09:01:13 +04:00
|
|
|
func (cfg *LevelDBConfig) adjust() {
|
|
|
|
cfg.CacheSize = getDefault(4*MB, cfg.CacheSize)
|
|
|
|
cfg.BlockSize = getDefault(4*KB, cfg.BlockSize)
|
|
|
|
cfg.WriteBufferSize = getDefault(4*MB, cfg.WriteBufferSize)
|
|
|
|
cfg.MaxOpenFiles = getDefault(1024, cfg.MaxOpenFiles)
|
2017-11-27 03:51:18 +03:00
|
|
|
cfg.MaxFileSize = getDefault(32*MB, cfg.MaxFileSize)
|
2014-10-24 09:01:13 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
func (cfg *RocksDBConfig) adjust() {
|
|
|
|
cfg.CacheSize = getDefault(4*MB, cfg.CacheSize)
|
|
|
|
cfg.BlockSize = getDefault(4*KB, cfg.BlockSize)
|
|
|
|
cfg.WriteBufferSize = getDefault(4*MB, cfg.WriteBufferSize)
|
|
|
|
cfg.MaxOpenFiles = getDefault(1024, cfg.MaxOpenFiles)
|
|
|
|
cfg.MaxWriteBufferNum = getDefault(2, cfg.MaxWriteBufferNum)
|
|
|
|
cfg.MinWriteBufferNumberToMerge = getDefault(1, cfg.MinWriteBufferNumberToMerge)
|
|
|
|
cfg.NumLevels = getDefault(7, cfg.NumLevels)
|
|
|
|
cfg.Level0FileNumCompactionTrigger = getDefault(4, cfg.Level0FileNumCompactionTrigger)
|
|
|
|
cfg.Level0SlowdownWritesTrigger = getDefault(16, cfg.Level0SlowdownWritesTrigger)
|
|
|
|
cfg.Level0StopWritesTrigger = getDefault(64, cfg.Level0StopWritesTrigger)
|
|
|
|
cfg.TargetFileSizeBase = getDefault(32*MB, cfg.TargetFileSizeBase)
|
|
|
|
cfg.TargetFileSizeMultiplier = getDefault(1, cfg.TargetFileSizeMultiplier)
|
|
|
|
cfg.MaxBytesForLevelBase = getDefault(32*MB, cfg.MaxBytesForLevelBase)
|
|
|
|
cfg.MaxBytesForLevelMultiplier = getDefault(1, cfg.MaxBytesForLevelMultiplier)
|
|
|
|
cfg.MaxBackgroundCompactions = getDefault(1, cfg.MaxBackgroundCompactions)
|
|
|
|
cfg.MaxBackgroundFlushes = getDefault(1, cfg.MaxBackgroundFlushes)
|
|
|
|
cfg.StatsDumpPeriodSec = getDefault(3600, cfg.StatsDumpPeriodSec)
|
|
|
|
cfg.BackgroundThreads = getDefault(2, cfg.BackgroundThreads)
|
|
|
|
cfg.HighPriorityBackgroundThreads = getDefault(1, cfg.HighPriorityBackgroundThreads)
|
2017-07-31 04:51:35 +03:00
|
|
|
cfg.MaxManifestFileSize = getDefault(20*MB, cfg.MaxManifestFileSize)
|
2014-08-07 12:49:48 +04:00
|
|
|
}
|
2014-10-08 12:02:00 +04:00
|
|
|
|
|
|
|
func (cfg *Config) Dump(w io.Writer) error {
|
2017-06-08 18:01:11 +03:00
|
|
|
data, err := toml.Marshal(*cfg)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if _, err := w.Write(data); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
2014-10-08 12:02:00 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
func (cfg *Config) DumpFile(fileName string) error {
|
|
|
|
var b bytes.Buffer
|
|
|
|
|
|
|
|
if err := cfg.Dump(&b); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return ioutil2.WriteFileAtomic(fileName, b.Bytes(), 0644)
|
|
|
|
}
|
2014-10-08 12:20:09 +04:00
|
|
|
|
|
|
|
func (cfg *Config) Rewrite() error {
|
|
|
|
if len(cfg.FileName) == 0 {
|
|
|
|
return ErrNoConfigFile
|
|
|
|
}
|
|
|
|
|
|
|
|
return cfg.DumpFile(cfg.FileName)
|
|
|
|
}
|
2014-11-01 18:28:28 +03:00
|
|
|
|
|
|
|
func (cfg *Config) GetReadonly() bool {
|
|
|
|
cfg.m.RLock()
|
|
|
|
b := cfg.Readonly
|
|
|
|
cfg.m.RUnlock()
|
|
|
|
return b
|
|
|
|
}
|
|
|
|
|
|
|
|
func (cfg *Config) SetReadonly(b bool) {
|
|
|
|
cfg.m.Lock()
|
|
|
|
cfg.Readonly = b
|
|
|
|
cfg.m.Unlock()
|
|
|
|
}
|