Reload hook (#1445)

* Add reload directive

* gofmt

* Fix default jitter and error message

* remove unneeded call to NextArg, add a couple negative setup tests

* Review feedback
This commit is contained in:
John Belamaric
2018-01-27 05:42:57 -05:00
committed by Miek Gieben
parent 80050766fb
commit 0b35d4d28f
7 changed files with 237 additions and 0 deletions

65
plugin/reload/reload.go Normal file
View File

@@ -0,0 +1,65 @@
package reload
import (
"crypto/md5"
"log"
"time"
"github.com/mholt/caddy"
)
// reload periodically checks if the Corefile has changed, and reloads if so
type reload struct {
instance *caddy.Instance
interval time.Duration
sum [md5.Size]byte
stopped bool
quit chan bool
}
func hook(event caddy.EventName, info interface{}) error {
if event != caddy.InstanceStartupEvent {
return nil
}
// if reload is removed from the Corefile, then the hook
// is still registered but setup is never called again
// so we need a flag to tell us not to reload
if r.stopped {
return nil
}
// this should be an instance. ok to panic if not
r.instance = info.(*caddy.Instance)
r.sum = md5.Sum(r.instance.Caddyfile().Body())
go func() {
tick := time.NewTicker(r.interval)
for {
select {
case <-tick.C:
corefile, err := caddy.LoadCaddyfile(r.instance.Caddyfile().ServerType())
if err != nil {
continue
}
s := md5.Sum(corefile.Body())
if s != r.sum {
_, err := r.instance.Restart(corefile)
if err != nil {
log.Printf("[ERROR] Corefile changed but reload failed: %s\n", err)
continue
}
// we are done, this hook gets called again with new instance
r.stopped = true
return
}
case <-r.quit:
return
}
}
}()
return nil
}