Issue on loading the configuration on file scope global variable.
The config setting and and loading config values inside main method
func main() {
if err := config.LoadConfig(); err != nil {
logrus.Info("Unable to read config : ")
os.Exit(-1)
}
fmt.Println(config.GetConfig().Value) // print the correct value
service.Test() // prints 0
}
my config setting. config.go
var appConfig AppConfig
func LoadConfig() error {
// loads config
appConfig = ....
}
func GetConfig() AppConfig {
return appConfig
}
I have another service file with global variable defined inside service.go
var x = config.GetConfig().Value
func Test(){
fmt.Println(x)
}
Question:
Why my global variable x inside service.go is not initialized ?
Thanks
Per the Go specification, the order of execution is as follows:
Package initialization—variable initialization and the invocation of init functions—happens in a single goroutine, sequentially, one package at a time. An init function may launch other goroutines, which can run concurrently with the initialization code. However, initialization always sequences the init functions: it will not invoke the next one until the previous one has returned.
Program execution begins by initializing the main package and then invoking the function main. When that function invocation returns, the program exits. It does not wait for other (non-main) goroutines to complete.
Meaning the order is roughly:
init()
functions runmain()
runsSo your global initialization is happening before main()
has a chance to load your configuration.
x
is being defined before your main or test methods are invoked, which means appConfig
hasn't been initialized yet (as appConfig is initialized by a call to LoadConfig
).
In order for x to be initialize-able in the way that you seem to want, you'd need appConfig to be initialized prior to main/test execution. Instead of calling LoadConfig
, you'd instead want to have something like:
var appConfig = NewConfig()