From d588664bfa39b96e68407daa1e2e6696dbb84b3a Mon Sep 17 00:00:00 2001 From: yusing Date: Sun, 7 Sep 2025 11:15:35 +0800 Subject: [PATCH] fix: prevent panicking on misconfigurations --- internal/route/reverse_proxy.go | 6 +++--- internal/route/route.go | 21 ++++++++++----------- internal/types/idlewatcher.go | 12 ++++++++++-- internal/watcher/health/monitor/monitor.go | 3 +++ 4 files changed, 26 insertions(+), 16 deletions(-) diff --git a/internal/route/reverse_proxy.go b/internal/route/reverse_proxy.go index 0239cde2..1286a3af 100755 --- a/internal/route/reverse_proxy.go +++ b/internal/route/reverse_proxy.go @@ -179,13 +179,13 @@ func (r *ReveseProxyRoute) addToLoadBalancer(parent task.Parent) { _ = lb.Start(parent) // always return nil linked = &ReveseProxyRoute{ Route: &Route{ - Alias: cfg.Link, - Homepage: r.Homepage, - HealthMon: lb, + Alias: cfg.Link, + Homepage: r.Homepage, }, loadBalancer: lb, handler: lb, } + linked.SetHealthMonitor(lb) routes.HTTP.AddKey(cfg.Link, linked) routes.All.AddKey(cfg.Link, linked) r.task.OnFinished("remove_loadbalancer_route", func() { diff --git a/internal/route/route.go b/internal/route/route.go index 4c0c762f..a1dea29b 100644 --- a/internal/route/route.go +++ b/internal/route/route.go @@ -51,9 +51,6 @@ type ( Agent string `json:"agent,omitempty"` Idlewatcher *types.IdlewatcherConfig `json:"idlewatcher,omitempty" extensions:"x-nullable"` - HealthMon types.HealthMonitor `json:"health,omitempty" swaggerignore:"true"` - // for swagger - HealthJSON *types.HealthJSON `json:",omitempty" form:"health"` Metadata `deserialize:"-"` } @@ -70,6 +67,10 @@ type ( Excluded *bool `json:"excluded"` + HealthMon types.HealthMonitor `json:"health,omitempty" swaggerignore:"true"` + // for swagger + HealthJSON *types.HealthJSON `json:",omitempty" form:"health"` + impl types.Route task *task.Task @@ -466,7 +467,7 @@ func (r *Route) UseLoadBalance() bool { } func (r *Route) UseIdleWatcher() bool { - return r.Idlewatcher != nil && r.Idlewatcher.IdleTimeout > 0 + return r.Idlewatcher != nil && r.Idlewatcher.IdleTimeout > 0 && r.Idlewatcher.ValErr() == nil } func (r *Route) UseHealthCheck() bool { @@ -582,13 +583,11 @@ func (r *Route) Finalize() { r.HealthCheck = types.DefaultHealthConfig() } - if !r.HealthCheck.Disable { - if r.HealthCheck.Interval == 0 { - r.HealthCheck.Interval = common.HealthCheckIntervalDefault - } - if r.HealthCheck.Timeout == 0 { - r.HealthCheck.Timeout = common.HealthCheckTimeoutDefault - } + if r.HealthCheck.Interval == 0 { + r.HealthCheck.Interval = common.HealthCheckIntervalDefault + } + if r.HealthCheck.Timeout == 0 { + r.HealthCheck.Timeout = common.HealthCheckTimeoutDefault } } diff --git a/internal/types/idlewatcher.go b/internal/types/idlewatcher.go index 0d7d2b50..1be60d2a 100644 --- a/internal/types/idlewatcher.go +++ b/internal/types/idlewatcher.go @@ -30,6 +30,8 @@ type ( StartEndpoint string `json:"start_endpoint,omitempty"` // Optional path that must be hit to start container DependsOn []string `json:"depends_on,omitempty"` + + valErr gperr.Error } // @name IdlewatcherConfig ContainerStopMethod string // @name ContainerStopMethod ContainerSignal string // @name ContainerSignal @@ -70,9 +72,10 @@ func (c *IdlewatcherConfig) ContainerName() string { func (c *IdlewatcherConfig) Validate() gperr.Error { if c.IdleTimeout == 0 { // zero idle timeout means no idle watcher + c.valErr = nil return nil } - errs := gperr.NewBuilder("idlewatcher config validation error") + errs := gperr.NewBuilder() errs.AddRange( c.validateProvider(), c.validateTimeouts(), @@ -80,7 +83,12 @@ func (c *IdlewatcherConfig) Validate() gperr.Error { c.validateStopSignal(), c.validateStartEndpoint(), ) - return errs.Error() + c.valErr = errs.Error() + return c.valErr +} + +func (c *IdlewatcherConfig) ValErr() gperr.Error { + return c.valErr } func (c *IdlewatcherConfig) validateProvider() error { diff --git a/internal/watcher/health/monitor/monitor.go b/internal/watcher/health/monitor/monitor.go index c1679b4c..6023ad35 100644 --- a/internal/watcher/health/monitor/monitor.go +++ b/internal/watcher/health/monitor/monitor.go @@ -72,6 +72,9 @@ func NewMonitor(r types.Route) types.HealthMonCheck { func newMonitor(u *url.URL, config *types.HealthCheckConfig, healthCheckFunc HealthCheckFunc) *monitor { if config.Retries == 0 { + if config.Interval == 0 { + config.Interval = common.HealthCheckIntervalDefault + } config.Retries = int64(common.HealthCheckDownNotifyDelayDefault / config.Interval) } mon := &monitor{