caddy/caddy.go
Matthew Holt 27ff6aeccb Fix goroutine leak in Run
D'oh, the servers' Shutdown() would never be called because they were
never added to the list of servers.

Thanks Danny for finding this.
2019-03-27 12:36:30 -06:00

81 lines
1.7 KiB
Go

package caddy2
import (
"encoding/json"
"fmt"
"log"
"strings"
"sync"
"time"
)
var currentCfg *Config
var currentCfgMu sync.Mutex
// Start runs Caddy with the given config.
func Start(cfg Config) error {
cfg.runners = make(map[string]Runner)
for modName, rawMsg := range cfg.Modules {
mod, ok := modules[modName]
if !ok {
return fmt.Errorf("unrecognized module: %s", modName)
}
val, err := LoadModule(mod, rawMsg)
if err != nil {
return fmt.Errorf("loading module '%s': %v", modName, err)
}
cfg.runners[modName] = val.(Runner)
}
for name, r := range cfg.runners {
err := r.Run()
if err != nil {
// TODO: If any one has an error, stop the others
return fmt.Errorf("%s module: %v", name, err)
}
}
currentCfgMu.Lock()
if currentCfg != nil {
for _, r := range cfg.runners {
err := r.Cancel()
if err != nil {
log.Println(err)
}
}
}
currentCfg = &cfg
currentCfgMu.Unlock()
return nil
}
// Runner is a thing that Caddy runs.
type Runner interface {
Run() error
Cancel() error
}
// Config represents a Caddy configuration.
type Config struct {
TestVal string `json:"testval"`
Modules map[string]json.RawMessage `json:"modules"`
runners map[string]Runner
}
// Duration is a JSON-string-unmarshable duration type.
type Duration time.Duration
// UnmarshalJSON satisfies json.Unmarshaler.
func (d *Duration) UnmarshalJSON(b []byte) (err error) {
dd, err := time.ParseDuration(strings.Trim(string(b), `"`))
cd := Duration(dd)
d = &cd
return
}
// MarshalJSON satisfies json.Marshaler.
func (d Duration) MarshalJSON() (b []byte, err error) {
return []byte(fmt.Sprintf(`"%s"`, time.Duration(d).String())), nil
}