Commit 98cf2637 authored by Matt Holt's avatar Matt Holt

Merge pull request #873 from mholt/fix-restart

Fix restart on USR1 not loading new Caddyfile
parents 6492592b ff820571
...@@ -65,7 +65,7 @@ type Instance struct { ...@@ -65,7 +65,7 @@ type Instance struct {
caddyfileInput Input caddyfileInput Input
// wg is used to wait for all servers to shut down // wg is used to wait for all servers to shut down
wg sync.WaitGroup wg *sync.WaitGroup
// servers is the list of servers with their listeners... // servers is the list of servers with their listeners...
servers []serverListener servers []serverListener
...@@ -89,12 +89,14 @@ func (i *Instance) Stop() error { ...@@ -89,12 +89,14 @@ func (i *Instance) Stop() error {
} }
// splice instance list to delete this one // splice instance list to delete this one
instancesMu.Lock()
for j, other := range instances { for j, other := range instances {
if other == i { if other == i {
instances = append(instances[:j], instances[j+1:]...) instances = append(instances[:j], instances[j+1:]...)
break break
} }
} }
instancesMu.Unlock()
return nil return nil
} }
...@@ -119,6 +121,9 @@ func (i *Instance) shutdownCallbacks() []error { ...@@ -119,6 +121,9 @@ func (i *Instance) shutdownCallbacks() []error {
func (i *Instance) Restart(newCaddyfile Input) (*Instance, error) { func (i *Instance) Restart(newCaddyfile Input) (*Instance, error) {
log.Println("[INFO] Reloading") log.Println("[INFO] Reloading")
i.wg.Add(1)
defer i.wg.Done()
// run restart callbacks // run restart callbacks
for _, fn := range i.onRestart { for _, fn := range i.onRestart {
err := fn() err := fn()
...@@ -142,7 +147,7 @@ func (i *Instance) Restart(newCaddyfile Input) (*Instance, error) { ...@@ -142,7 +147,7 @@ func (i *Instance) Restart(newCaddyfile Input) (*Instance, error) {
} }
// create new instance; if the restart fails, it is simply discarded // create new instance; if the restart fails, it is simply discarded
newInst := &Instance{serverType: newCaddyfile.ServerType()} newInst := &Instance{serverType: newCaddyfile.ServerType(), wg: i.wg}
// attempt to start new instance // attempt to start new instance
err := startWithListenerFds(newCaddyfile, newInst, restartFds) err := startWithListenerFds(newCaddyfile, newInst, restartFds)
...@@ -150,15 +155,8 @@ func (i *Instance) Restart(newCaddyfile Input) (*Instance, error) { ...@@ -150,15 +155,8 @@ func (i *Instance) Restart(newCaddyfile Input) (*Instance, error) {
return i, err return i, err
} }
// success! bump the old instance out so it will be garbage-collected // success! stop the old instance
instancesMu.Lock() i.Stop()
for j, other := range instances {
if other == i {
instances = append(instances[:j], instances[j+1:]...)
break
}
}
instancesMu.Unlock()
log.Println("[INFO] Reloading complete") log.Println("[INFO] Reloading complete")
...@@ -365,7 +363,7 @@ func (i *Instance) Caddyfile() Input { ...@@ -365,7 +363,7 @@ func (i *Instance) Caddyfile() Input {
// This function blocks until all the servers are listening. // This function blocks until all the servers are listening.
func Start(cdyfile Input) (*Instance, error) { func Start(cdyfile Input) (*Instance, error) {
writePidFile() writePidFile()
inst := &Instance{serverType: cdyfile.ServerType()} inst := &Instance{serverType: cdyfile.ServerType(), wg: new(sync.WaitGroup)}
return inst, startWithListenerFds(cdyfile, inst, nil) return inst, startWithListenerFds(cdyfile, inst, nil)
} }
...@@ -405,13 +403,10 @@ func startWithListenerFds(cdyfile Input, inst *Instance, restartFds map[string]r ...@@ -405,13 +403,10 @@ func startWithListenerFds(cdyfile Input, inst *Instance, restartFds map[string]r
return err return err
} }
if restartFds == nil { for _, startupFunc := range inst.onStartup {
// run startup callbacks since this is not a restart err := startupFunc()
for _, startupFunc := range inst.onStartup { if err != nil {
err := startupFunc() return err
if err != nil {
return err
}
} }
} }
...@@ -532,7 +527,6 @@ func startServers(serverList []Server, inst *Instance, restartFds map[string]res ...@@ -532,7 +527,6 @@ func startServers(serverList []Server, inst *Instance, restartFds map[string]res
return err return err
} }
file.Close() file.Close()
delete(restartFds, addr)
} }
} }
...@@ -552,15 +546,6 @@ func startServers(serverList []Server, inst *Instance, restartFds map[string]res ...@@ -552,15 +546,6 @@ func startServers(serverList []Server, inst *Instance, restartFds map[string]res
inst.servers = append(inst.servers, serverListener{server: s, listener: ln}) inst.servers = append(inst.servers, serverListener{server: s, listener: ln})
} }
// Close the remaining (unused) file descriptors to free up resources
// and stop old servers that aren't used anymore
for key, old := range restartFds {
if err := old.server.Stop(); err != nil {
log.Printf("[ERROR] Stopping %s: %v", old.server.Address(), err)
}
delete(restartFds, key)
}
// Log errors that may be returned from Serve() calls, // Log errors that may be returned from Serve() calls,
// these errors should only be occurring in the server loop. // these errors should only be occurring in the server loop.
go func() { go func() {
......
...@@ -51,7 +51,8 @@ var contexts []*httpContext ...@@ -51,7 +51,8 @@ var contexts []*httpContext
func newContext() caddy.Context { func newContext() caddy.Context {
context := &httpContext{keysToSiteConfigs: make(map[string]*SiteConfig)} context := &httpContext{keysToSiteConfigs: make(map[string]*SiteConfig)}
contexts = append(contexts, context) // put the new context at start to allow setup of directives on new instance
contexts = append([]*httpContext{context}, contexts...)
return context return context
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment