diff --git a/config/config.go b/config/config.go index d413bde7..b47acf8e 100644 --- a/config/config.go +++ b/config/config.go @@ -66,9 +66,15 @@ func Load(filename string, input io.Reader) (Group, error) { // server config and the dispenser containing only // this directive's tokens. controller := &setup.Controller{ - Config: &config, - Dispenser: parse.NewDispenserTokens(filename, tokens), - OncePerServerBlock: func(f func()) { onces[dir.name].Do(f) }, + Config: &config, + Dispenser: parse.NewDispenserTokens(filename, tokens), + OncePerServerBlock: func(f func() error) error { + var err error + onces[dir.name].Do(func() { + err = f() + }) + return err + }, } midware, err := dir.setup(controller) diff --git a/config/setup/controller.go b/config/setup/controller.go index 3b78dbcd..d0b0ee89 100644 --- a/config/setup/controller.go +++ b/config/setup/controller.go @@ -19,8 +19,11 @@ type Controller struct { // OncePerServerBlock is a function that executes f // exactly once per server block, no matter how many - // hosts are associated with it. - OncePerServerBlock func(f func()) + // hosts are associated with it. If it is the first + // time, the function f is executed immediately + // (not deferred) and may return an error which is + // returned by OncePerServerBlock. + OncePerServerBlock func(f func() error) error } // NewTestController creates a new *Controller for diff --git a/config/setup/startupshutdown.go b/config/setup/startupshutdown.go index ddcd1e64..e4d87305 100644 --- a/config/setup/startupshutdown.go +++ b/config/setup/startupshutdown.go @@ -55,9 +55,8 @@ func registerCallback(c *Controller, list *[]func() error) error { funcs = append(funcs, fn) } - c.OncePerServerBlock(func() { + return c.OncePerServerBlock(func() error { *list = append(*list, funcs...) + return nil }) - - return nil }