mirror of
https://github.com/caddyserver/caddy.git
synced 2024-12-23 22:27:38 -05:00
Merge pull request #333 from mholt/firststartup
startup: Only run commands at first startup
This commit is contained in:
commit
fc6afe2a8b
5 changed files with 49 additions and 5 deletions
|
@ -71,6 +71,10 @@ var (
|
|||
// index in the list of inherited file descriptors. This
|
||||
// variable is not safe for concurrent access.
|
||||
loadedGob caddyfileGob
|
||||
|
||||
// startedBefore should be set to true if caddy has been
|
||||
// started at least once.
|
||||
startedBefore bool
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -128,6 +132,7 @@ func Start(cdyfile Input) (err error) {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
startedBefore = true
|
||||
|
||||
// Close remaining file descriptors we may have inherited that we don't need
|
||||
if IsRestart() {
|
||||
|
@ -203,6 +208,18 @@ func startServers(groupings bindingGroup) error {
|
|||
wg.Add(1)
|
||||
go func(s *server.Server, ln server.ListenerFile) {
|
||||
defer wg.Done()
|
||||
|
||||
// run startup functions that should only execute when
|
||||
// the original parent process is starting.
|
||||
if !IsRestart() && !startedBefore {
|
||||
err := s.RunFirstStartupFuncs()
|
||||
if err != nil {
|
||||
errChan <- err
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// start the server
|
||||
if ln != nil {
|
||||
errChan <- s.Serve(ln)
|
||||
} else {
|
||||
|
|
|
@ -10,7 +10,7 @@ import (
|
|||
|
||||
// Startup registers a startup callback to execute during server start.
|
||||
func Startup(c *Controller) (middleware.Middleware, error) {
|
||||
return nil, registerCallback(c, &c.Startup)
|
||||
return nil, registerCallback(c, &c.FirstStartup)
|
||||
}
|
||||
|
||||
// Shutdown registers a shutdown callback to execute during process exit.
|
||||
|
|
|
@ -45,7 +45,7 @@ func TestStartup(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Errorf("Expected no errors, got: %v", err)
|
||||
}
|
||||
err = c.Startup[0]()
|
||||
err = c.FirstStartup[0]()
|
||||
if err != nil && !test.shouldExecutionErr {
|
||||
t.Errorf("Test %d recieved an error of:\n%v", i, err)
|
||||
}
|
||||
|
|
|
@ -26,11 +26,21 @@ type Config struct {
|
|||
// Middleware stack; map of path scope to middleware -- TODO: Support path scope?
|
||||
Middleware map[string][]middleware.Middleware
|
||||
|
||||
// Functions (or methods) to execute at server start; these
|
||||
// are executed before any parts of the server are configured,
|
||||
// and the functions are blocking
|
||||
// Startup is a list of functions (or methods) to execute at
|
||||
// server startup and restart; these are executed before any
|
||||
// parts of the server are configured, and the functions are
|
||||
// blocking. These are good for setting up middlewares and
|
||||
// starting goroutines.
|
||||
Startup []func() error
|
||||
|
||||
// FirstStartup is like Startup but these functions only execute
|
||||
// during the initial startup, not on subsequent restarts.
|
||||
//
|
||||
// (Note: The server does not ever run these on its own; it is up
|
||||
// to the calling application to do so, and do so only once, as the
|
||||
// server itself has no notion whether it's a restart or not.)
|
||||
FirstStartup []func() error
|
||||
|
||||
// Functions (or methods) to execute when the server quits;
|
||||
// these are executed in response to SIGINT and are blocking
|
||||
Shutdown []func() error
|
||||
|
|
|
@ -371,6 +371,23 @@ func setupClientAuth(tlsConfigs []TLSConfig, config *tls.Config) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// RunFirstStartupFuncs runs all of the server's FirstStartup
|
||||
// callback functions unless one of them returns an error first.
|
||||
// It is up the caller's responsibility to call this only once and
|
||||
// at the correct time. The functions here should not be executed
|
||||
// at restarts or where the user does not explicitly start a new
|
||||
// instance of the server.
|
||||
func (s *Server) RunFirstStartupFuncs() error {
|
||||
for _, vh := range s.vhosts {
|
||||
for _, f := range vh.config.FirstStartup {
|
||||
if err := f(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// tcpKeepAliveListener sets TCP keep-alive timeouts on accepted
|
||||
// connections. It's used by ListenAndServe and ListenAndServeTLS so
|
||||
// dead TCP connections (e.g. closing laptop mid-download) eventually
|
||||
|
|
Loading…
Reference in a new issue