* app: optimize config file reading
* read config file just once (even when upgrading) * don't call os.Stat()
This commit is contained in:
parent
2dd6ea5161
commit
3ee8051e97
31
app.go
31
app.go
|
@ -93,16 +93,17 @@ func run(args options) {
|
|||
os.Exit(0)
|
||||
}()
|
||||
|
||||
// Do the upgrade if necessary
|
||||
err := upgradeConfig()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
if !config.firstRun {
|
||||
// Do the upgrade if necessary
|
||||
err := upgradeConfig()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// parse from config file
|
||||
err = parseConfig()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
err = parseConfig()
|
||||
if err != nil {
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
if (runtime.GOOS == "linux" || runtime.GOOS == "darwin") &&
|
||||
|
@ -120,10 +121,12 @@ func run(args options) {
|
|||
|
||||
loadFilters()
|
||||
|
||||
// Save the updated config
|
||||
err = config.write()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
if !config.firstRun {
|
||||
// Save the updated config
|
||||
err := config.write()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Init the DNS server instance before registering HTTP handlers
|
||||
|
@ -131,7 +134,7 @@ func run(args options) {
|
|||
initDNSServer(dnsBaseDir)
|
||||
|
||||
if !config.firstRun {
|
||||
err = startDNSServer()
|
||||
err := startDNSServer()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
|
31
config.go
31
config.go
|
@ -30,6 +30,10 @@ type logSettings struct {
|
|||
// configuration is loaded from YAML
|
||||
// field ordering is important -- yaml fields will mirror ordering from here
|
||||
type configuration struct {
|
||||
// Raw file data to avoid re-reading of configuration file
|
||||
// It's reset after config is parsed
|
||||
fileData []byte
|
||||
|
||||
ourConfigFilename string // Config filename (can be overridden via the command line arguments)
|
||||
ourWorkingDir string // Location of our directory, used to protect against CWD being somewhere else
|
||||
firstRun bool // if set to true, don't run any services except HTTP web inteface, and serve only first-run html
|
||||
|
@ -174,7 +178,7 @@ func (c *configuration) getConfigFilename() string {
|
|||
func getLogSettings() logSettings {
|
||||
l := logSettings{}
|
||||
yamlFile, err := readConfigFile()
|
||||
if err != nil || yamlFile == nil {
|
||||
if err != nil {
|
||||
return l
|
||||
}
|
||||
err = yaml.Unmarshal(yamlFile, &l)
|
||||
|
@ -190,13 +194,9 @@ func parseConfig() error {
|
|||
log.Debug("Reading config file: %s", configFile)
|
||||
yamlFile, err := readConfigFile()
|
||||
if err != nil {
|
||||
log.Error("Couldn't read config file: %s", err)
|
||||
return err
|
||||
}
|
||||
if yamlFile == nil {
|
||||
log.Error("YAML file doesn't exist, skipping it")
|
||||
return nil
|
||||
}
|
||||
config.fileData = nil
|
||||
err = yaml.Unmarshal(yamlFile, &config)
|
||||
if err != nil {
|
||||
log.Error("Couldn't parse config file: %s", err)
|
||||
|
@ -213,22 +213,23 @@ func parseConfig() error {
|
|||
|
||||
// readConfigFile reads config file contents if it exists
|
||||
func readConfigFile() ([]byte, error) {
|
||||
configFile := config.getConfigFilename()
|
||||
if _, err := os.Stat(configFile); os.IsNotExist(err) {
|
||||
// do nothing, file doesn't exist
|
||||
return nil, nil
|
||||
if len(config.fileData) != 0 {
|
||||
return config.fileData, nil
|
||||
}
|
||||
return ioutil.ReadFile(configFile)
|
||||
|
||||
configFile := config.getConfigFilename()
|
||||
d, err := ioutil.ReadFile(configFile)
|
||||
if err != nil {
|
||||
log.Error("Couldn't read config file %s: %s", configFile, err)
|
||||
return nil, err
|
||||
}
|
||||
return d, nil
|
||||
}
|
||||
|
||||
// Saves configuration to the YAML file and also saves the user filter contents to a file
|
||||
func (c *configuration) write() error {
|
||||
c.Lock()
|
||||
defer c.Unlock()
|
||||
if config.firstRun {
|
||||
log.Debug("Silently refusing to write config because first run and not configured yet")
|
||||
return nil
|
||||
}
|
||||
configFile := config.getConfigFilename()
|
||||
log.Debug("Writing YAML file: %s", configFile)
|
||||
yamlText, err := yaml.Marshal(&config)
|
||||
|
|
12
upgrade.go
12
upgrade.go
|
@ -2,7 +2,6 @@ package main
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
|
@ -16,21 +15,15 @@ const currentSchemaVersion = 3 // used for upgrading from old configs to new con
|
|||
// Performs necessary upgrade operations if needed
|
||||
func upgradeConfig() error {
|
||||
// read a config file into an interface map, so we can manipulate values without losing any
|
||||
configFile := config.getConfigFilename()
|
||||
if _, err := os.Stat(configFile); os.IsNotExist(err) {
|
||||
log.Printf("config file %s does not exist, nothing to upgrade", configFile)
|
||||
return nil
|
||||
}
|
||||
diskConfig := map[string]interface{}{}
|
||||
body, err := ioutil.ReadFile(configFile)
|
||||
body, err := readConfigFile()
|
||||
if err != nil {
|
||||
log.Printf("Couldn't read config file '%s': %s", configFile, err)
|
||||
return err
|
||||
}
|
||||
|
||||
err = yaml.Unmarshal(body, &diskConfig)
|
||||
if err != nil {
|
||||
log.Printf("Couldn't parse config file '%s': %s", configFile, err)
|
||||
log.Printf("Couldn't parse config file: %s", err)
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -87,6 +80,7 @@ func upgradeConfigSchema(oldVersion int, diskConfig *map[string]interface{}) err
|
|||
return err
|
||||
}
|
||||
|
||||
config.fileData = body
|
||||
err = file.SafeWrite(configFile, body)
|
||||
if err != nil {
|
||||
log.Printf("Couldn't save YAML config: %s", err)
|
||||
|
|
Loading…
Reference in New Issue