diff --git a/internal/config/events.go b/internal/config/events.go index 82aacda4..c64f4c25 100644 --- a/internal/config/events.go +++ b/internal/config/events.go @@ -52,11 +52,16 @@ func logNotifyWarn(action string, err error) { }) } +var nilState *state + func Load() error { if HasState() { panic(errors.New("config already loaded")) } state := NewState() + config.WorkingState.Store(state) + defer config.WorkingState.Store(nilState) + cfgWatcher = watcher.NewConfigFileWatcher(common.ConfigFileName) initErr := state.InitFromFile(common.ConfigPath) @@ -82,6 +87,9 @@ func Reload() gperr.Error { defer reloadMu.Unlock() newState := NewState() + config.WorkingState.Store(newState) + defer config.WorkingState.Store(nilState) + err := newState.InitFromFile(common.ConfigPath) if err != nil { newState.Task().FinishAndWait(err) diff --git a/internal/config/types/state.go b/internal/config/types/state.go index 2de2433c..bbd5d870 100644 --- a/internal/config/types/state.go +++ b/internal/config/types/state.go @@ -33,7 +33,10 @@ type State interface { FlushTmpLog() } -// could be nil +// could be nil before first call on Load var ActiveState synk.Value[State] +// nil-safe while loading config, nil otherwise +var WorkingState synk.Value[State] + var ErrConfigChanged = errors.New("config changed") diff --git a/internal/route/route.go b/internal/route/route.go index 0aab578b..bc97bc7d 100644 --- a/internal/route/route.go +++ b/internal/route/route.go @@ -774,7 +774,7 @@ func (r *Route) Finalize() { } r.Port.Listening, r.Port.Proxy = lp, pp - r.HealthCheck.ApplyDefaults(config.ActiveConfig.Load().Defaults.HealthCheck) + r.HealthCheck.ApplyDefaults(config.WorkingState.Load().Value().Defaults.HealthCheck) } func (r *Route) FinalizeHomepageConfig() { diff --git a/internal/types/healthcheck_config.go b/internal/types/healthcheck_config.go index fceddef6..5490db6f 100644 --- a/internal/types/healthcheck_config.go +++ b/internal/types/healthcheck_config.go @@ -36,6 +36,9 @@ func (hc *HealthCheckConfig) ApplyDefaults(defaults HealthCheckConfig) { } } if hc.Retries == 0 { - hc.Retries = int64(HealthCheckDownNotifyDelayDefault / hc.Interval) + hc.Retries = defaults.Retries + if hc.Retries == 0 { + hc.Retries = max(1, int64(HealthCheckDownNotifyDelayDefault/hc.Interval)) + } } } diff --git a/internal/watcher/health/monitor/monitor.go b/internal/watcher/health/monitor/monitor.go index ffb62145..79499b06 100644 --- a/internal/watcher/health/monitor/monitor.go +++ b/internal/watcher/health/monitor/monitor.go @@ -74,7 +74,15 @@ func NewMonitor(r types.Route) types.HealthMonCheck { } func newMonitor(u *url.URL, cfg types.HealthCheckConfig, healthCheckFunc HealthCheckFunc) *monitor { - cfg.ApplyDefaults(config.DefaultConfig().Defaults.HealthCheck) + state := config.WorkingState.Load() + if state == nil { + state = config.ActiveState.Load() + } + if state != nil { + cfg.ApplyDefaults(state.Value().Defaults.HealthCheck) + } else { + cfg.ApplyDefaults(types.HealthCheckConfig{}) // use config defaults + } mon := &monitor{ config: cfg, checkHealth: healthCheckFunc,