github.com/hdt3213/godis@v1.2.9/config/config.go (about)

     1  package config
     2  
     3  import (
     4  	"bufio"
     5  	"io"
     6  	"os"
     7  	"path/filepath"
     8  	"reflect"
     9  	"strconv"
    10  	"strings"
    11  	"time"
    12  
    13  	"github.com/hdt3213/godis/lib/utils"
    14  
    15  	"github.com/hdt3213/godis/lib/logger"
    16  )
    17  
    18  var (
    19  	ClusterMode    = "cluster"
    20  	StandaloneMode = "standalone"
    21  )
    22  
    23  // ServerProperties defines global config properties
    24  type ServerProperties struct {
    25  	// for Public configuration
    26  	RunID             string `cfg:"runid"` // runID always different at every exec.
    27  	Bind              string `cfg:"bind"`
    28  	Port              int    `cfg:"port"`
    29  	Dir               string `cfg:"dir"`
    30  	AppendOnly        bool   `cfg:"appendonly"`
    31  	AppendFilename    string `cfg:"appendfilename"`
    32  	AppendFsync       string `cfg:"appendfsync"`
    33  	AofUseRdbPreamble bool   `cfg:"aof-use-rdb-preamble"`
    34  	MaxClients        int    `cfg:"maxclients"`
    35  	RequirePass       string `cfg:"requirepass"`
    36  	Databases         int    `cfg:"databases"`
    37  	RDBFilename       string `cfg:"dbfilename"`
    38  	MasterAuth        string `cfg:"masterauth"`
    39  	SlaveAnnouncePort int    `cfg:"slave-announce-port"`
    40  	SlaveAnnounceIP   string `cfg:"slave-announce-ip"`
    41  	ReplTimeout       int    `cfg:"repl-timeout"`
    42  
    43  	// for cluster mode configuration
    44  	ClusterEnabled string   `cfg:"cluster-enabled"` // Not used at present.
    45  	Peers          []string `cfg:"peers"`
    46  	Self           string   `cfg:"self"`
    47  
    48  	// config file path
    49  	CfPath string `cfg:"cf,omitempty"`
    50  }
    51  
    52  type ServerInfo struct {
    53  	StartUpTime time.Time
    54  }
    55  
    56  // Properties holds global config properties
    57  var Properties *ServerProperties
    58  var EachTimeServerInfo *ServerInfo
    59  
    60  func init() {
    61  	// A few stats we don't want to reset: server startup time, and peak mem.
    62  	EachTimeServerInfo = &ServerInfo{
    63  		StartUpTime: time.Now(),
    64  	}
    65  
    66  	// default config
    67  	Properties = &ServerProperties{
    68  		Bind:       "127.0.0.1",
    69  		Port:       6379,
    70  		AppendOnly: false,
    71  		RunID:      utils.RandString(40),
    72  	}
    73  }
    74  
    75  func parse(src io.Reader) *ServerProperties {
    76  	config := &ServerProperties{}
    77  
    78  	// read config file
    79  	rawMap := make(map[string]string)
    80  	scanner := bufio.NewScanner(src)
    81  	for scanner.Scan() {
    82  		line := scanner.Text()
    83  		if len(line) > 0 && strings.TrimLeft(line, " ")[0] == '#' {
    84  			continue
    85  		}
    86  		pivot := strings.IndexAny(line, " ")
    87  		if pivot > 0 && pivot < len(line)-1 { // separator found
    88  			key := line[0:pivot]
    89  			value := strings.Trim(line[pivot+1:], " ")
    90  			rawMap[strings.ToLower(key)] = value
    91  		}
    92  	}
    93  	if err := scanner.Err(); err != nil {
    94  		logger.Fatal(err)
    95  	}
    96  
    97  	// parse format
    98  	t := reflect.TypeOf(config)
    99  	v := reflect.ValueOf(config)
   100  	n := t.Elem().NumField()
   101  	for i := 0; i < n; i++ {
   102  		field := t.Elem().Field(i)
   103  		fieldVal := v.Elem().Field(i)
   104  		key, ok := field.Tag.Lookup("cfg")
   105  		if !ok || strings.TrimLeft(key, " ") == "" {
   106  			key = field.Name
   107  		}
   108  		value, ok := rawMap[strings.ToLower(key)]
   109  		if ok {
   110  			// fill config
   111  			switch field.Type.Kind() {
   112  			case reflect.String:
   113  				fieldVal.SetString(value)
   114  			case reflect.Int:
   115  				intValue, err := strconv.ParseInt(value, 10, 64)
   116  				if err == nil {
   117  					fieldVal.SetInt(intValue)
   118  				}
   119  			case reflect.Bool:
   120  				boolValue := "yes" == value
   121  				fieldVal.SetBool(boolValue)
   122  			case reflect.Slice:
   123  				if field.Type.Elem().Kind() == reflect.String {
   124  					slice := strings.Split(value, ",")
   125  					fieldVal.Set(reflect.ValueOf(slice))
   126  				}
   127  			}
   128  		}
   129  	}
   130  	return config
   131  }
   132  
   133  // SetupConfig read config file and store properties into Properties
   134  func SetupConfig(configFilename string) {
   135  	file, err := os.Open(configFilename)
   136  	if err != nil {
   137  		panic(err)
   138  	}
   139  	defer file.Close()
   140  	Properties = parse(file)
   141  	Properties.RunID = utils.RandString(40)
   142  	configFilePath, err := filepath.Abs(configFilename)
   143  	if err != nil {
   144  		return
   145  	}
   146  	Properties.CfPath = configFilePath
   147  	if Properties.Dir == "" {
   148  		Properties.Dir = "."
   149  	}
   150  }
   151  
   152  func GetTmpDir() string {
   153  	return Properties.Dir + "/tmp"
   154  }