Reflect magic
This commit is contained in:
parent
d1131d158f
commit
be052e2c75
|
@ -4,6 +4,8 @@ import (
|
||||||
"flag"
|
"flag"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
|
"github.com/kr/pretty"
|
||||||
|
|
||||||
"github.com/localhots/secondly"
|
"github.com/localhots/secondly"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -40,8 +42,9 @@ func main() {
|
||||||
// Starting a web server
|
// Starting a web server
|
||||||
secondly.StartServer("", 5500)
|
secondly.StartServer("", 5500)
|
||||||
// Defining callbacks
|
// Defining callbacks
|
||||||
secondly.OnChange("AppName", func(o, n interface{}) {
|
secondly.OnChange("app_name", func(o, n interface{}) {
|
||||||
log.Printf("OMG! AppName changed from %q to %q", o, n)
|
log.Printf("OMG! AppName changed from %q to %q", o, n)
|
||||||
|
pretty.Println(conf)
|
||||||
})
|
})
|
||||||
|
|
||||||
// Other application startup logic
|
// Other application startup logic
|
||||||
|
|
29
secondly.go
29
secondly.go
|
@ -39,7 +39,7 @@ func Manage(target interface{}) {
|
||||||
panic("Argument must be a pointer to a struct")
|
panic("Argument must be a pointer to a struct")
|
||||||
}
|
}
|
||||||
|
|
||||||
config = target
|
assign(target)
|
||||||
|
|
||||||
bootstrap()
|
bootstrap()
|
||||||
}
|
}
|
||||||
|
@ -109,6 +109,17 @@ func OnChange(field string, fun func(oldVal, newVal interface{})) {
|
||||||
callbacks[field] = append(callbacks[field], fun)
|
callbacks[field] = append(callbacks[field], fun)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func assign(target interface{}) {
|
||||||
|
if config == nil {
|
||||||
|
config = target
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
cval := reflect.ValueOf(config).Elem()
|
||||||
|
tval := reflect.ValueOf(target).Elem()
|
||||||
|
cval.Set(tval)
|
||||||
|
}
|
||||||
|
|
||||||
func bootstrap() {
|
func bootstrap() {
|
||||||
if configFile == "" {
|
if configFile == "" {
|
||||||
log.Fatalln("path to config file is not set")
|
log.Fatalln("path to config file is not set")
|
||||||
|
@ -136,16 +147,20 @@ func writeConfig() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateConfig(body []byte) {
|
func updateConfig(body []byte) {
|
||||||
|
// Making a copy of old config for further comparison
|
||||||
|
old := duplicate(config)
|
||||||
|
// Making a second copy that we will fill with new data
|
||||||
dupe := duplicate(config)
|
dupe := duplicate(config)
|
||||||
|
|
||||||
if err := json.Unmarshal(body, dupe); err != nil {
|
if err := json.Unmarshal(body, dupe); err != nil {
|
||||||
panic("Failed to update config")
|
panic("Failed to update config")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
defer triggerCallbacks(config, dupe)
|
|
||||||
|
|
||||||
// Setting new config
|
// Setting new config
|
||||||
config = dupe
|
assign(dupe)
|
||||||
|
|
||||||
|
triggerCallbacks(old, dupe)
|
||||||
}
|
}
|
||||||
|
|
||||||
func marshal(obj interface{}) []byte {
|
func marshal(obj interface{}) []byte {
|
||||||
|
@ -210,7 +225,9 @@ func duplicate(original interface{}) interface{} {
|
||||||
// Now we need the type (name) of this struct
|
// Now we need the type (name) of this struct
|
||||||
typ := val.Type()
|
typ := val.Type()
|
||||||
// Creating a duplicate instance of that struct
|
// Creating a duplicate instance of that struct
|
||||||
dupe := reflect.New(typ).Interface()
|
dupe := reflect.New(typ)
|
||||||
|
// Value copy
|
||||||
|
dupe.Elem().Set(val)
|
||||||
|
|
||||||
return dupe
|
return dupe.Interface()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue