mirror of
https://github.com/yusing/godoxy.git
synced 2025-07-22 12:24:02 +02:00
fix: race condition in health monitor
This commit is contained in:
parent
2b91d99ec6
commit
2e8248cd5b
4 changed files with 22 additions and 16 deletions
|
@ -7,12 +7,14 @@ import (
|
||||||
|
|
||||||
"github.com/yusing/go-proxy/internal/common"
|
"github.com/yusing/go-proxy/internal/common"
|
||||||
"github.com/yusing/go-proxy/internal/gperr"
|
"github.com/yusing/go-proxy/internal/gperr"
|
||||||
|
gphttp "github.com/yusing/go-proxy/internal/net/gphttp"
|
||||||
|
"github.com/yusing/go-proxy/internal/net/gphttp/accesslog"
|
||||||
|
"github.com/yusing/go-proxy/internal/net/gphttp/middleware"
|
||||||
|
metricslogger "github.com/yusing/go-proxy/internal/net/gphttp/middleware/metrics_logger"
|
||||||
"github.com/yusing/go-proxy/internal/route/routes"
|
"github.com/yusing/go-proxy/internal/route/routes"
|
||||||
"github.com/yusing/go-proxy/internal/task"
|
"github.com/yusing/go-proxy/internal/task"
|
||||||
"github.com/yusing/go-proxy/internal/watcher/health"
|
"github.com/yusing/go-proxy/internal/watcher/health"
|
||||||
"github.com/yusing/go-proxy/internal/watcher/health/monitor"
|
"github.com/yusing/go-proxy/internal/watcher/health/monitor"
|
||||||
|
|
||||||
E "github.com/yusing/go-proxy/internal/error"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
|
@ -96,7 +98,7 @@ func (s *FileServer) Start(parent task.Parent) gperr.Error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.UseHealthCheck() {
|
if s.UseHealthCheck() {
|
||||||
s.Health = monitor.NewFileServerHealthMonitor(s.TargetName(), s.HealthCheck, s.Root)
|
s.Health = monitor.NewFileServerHealthMonitor(s.HealthCheck, s.Root)
|
||||||
if err := s.Health.Start(s.task); err != nil {
|
if err := s.Health.Start(s.task); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,10 +12,9 @@ type FileServerHealthMonitor struct {
|
||||||
path string
|
path string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewFileServerHealthMonitor(alias string, config *health.HealthCheckConfig, path string) *FileServerHealthMonitor {
|
func NewFileServerHealthMonitor(config *health.HealthCheckConfig, path string) *FileServerHealthMonitor {
|
||||||
mon := &FileServerHealthMonitor{path: path}
|
mon := &FileServerHealthMonitor{path: path}
|
||||||
mon.monitor = newMonitor(nil, config, mon.CheckHealth)
|
mon.monitor = newMonitor(nil, config, mon.CheckHealth)
|
||||||
mon.service = alias
|
|
||||||
return mon
|
return mon
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/yusing/go-proxy/internal/common"
|
"github.com/yusing/go-proxy/internal/gperr"
|
||||||
E "github.com/yusing/go-proxy/internal/error"
|
|
||||||
"github.com/yusing/go-proxy/internal/logging"
|
"github.com/yusing/go-proxy/internal/logging"
|
||||||
"github.com/yusing/go-proxy/internal/metrics"
|
"github.com/yusing/go-proxy/internal/metrics"
|
||||||
"github.com/yusing/go-proxy/internal/net/types"
|
"github.com/yusing/go-proxy/internal/net/types"
|
||||||
|
@ -26,7 +25,7 @@ type (
|
||||||
url atomic.Value[*types.URL]
|
url atomic.Value[*types.URL]
|
||||||
|
|
||||||
status atomic.Value[health.Status]
|
status atomic.Value[health.Status]
|
||||||
lastResult *health.HealthCheckResult
|
lastResult atomic.Value[*health.HealthCheckResult]
|
||||||
|
|
||||||
checkHealth HealthCheckFunc
|
checkHealth HealthCheckFunc
|
||||||
startTime time.Time
|
startTime time.Time
|
||||||
|
@ -140,10 +139,11 @@ func (mon *monitor) Uptime() time.Duration {
|
||||||
|
|
||||||
// Latency implements HealthMonitor.
|
// Latency implements HealthMonitor.
|
||||||
func (mon *monitor) Latency() time.Duration {
|
func (mon *monitor) Latency() time.Duration {
|
||||||
if mon.lastResult == nil {
|
res := mon.lastResult.Load()
|
||||||
|
if res == nil {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
return mon.lastResult.Latency
|
return res.Latency
|
||||||
}
|
}
|
||||||
|
|
||||||
// Name implements HealthMonitor.
|
// Name implements HealthMonitor.
|
||||||
|
@ -159,7 +159,13 @@ func (mon *monitor) String() string {
|
||||||
|
|
||||||
// MarshalJSON implements json.Marshaler of HealthMonitor.
|
// MarshalJSON implements json.Marshaler of HealthMonitor.
|
||||||
func (mon *monitor) MarshalJSON() ([]byte, error) {
|
func (mon *monitor) MarshalJSON() ([]byte, error) {
|
||||||
res := mon.lastResult
|
res := mon.lastResult.Load()
|
||||||
|
if res == nil {
|
||||||
|
res = &health.HealthCheckResult{
|
||||||
|
Healthy: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (&JSONRepresentation{
|
return (&JSONRepresentation{
|
||||||
Name: mon.service,
|
Name: mon.service,
|
||||||
Config: mon.config,
|
Config: mon.config,
|
||||||
|
@ -185,7 +191,7 @@ func (mon *monitor) checkUpdateHealth() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
mon.lastResult = result
|
mon.lastResult.Store(result)
|
||||||
var status health.Status
|
var status health.Status
|
||||||
if result.Healthy {
|
if result.Healthy {
|
||||||
status = health.StatusHealthy
|
status = health.StatusHealthy
|
||||||
|
|
|
@ -36,14 +36,13 @@ func (mon *RawHealthMonitor) CheckHealth() (result *health.HealthCheckResult, er
|
||||||
url := mon.url.Load()
|
url := mon.url.Load()
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
conn, dialErr := mon.dialer.DialContext(ctx, url.Scheme, url.Host)
|
conn, dialErr := mon.dialer.DialContext(ctx, url.Scheme, url.Host)
|
||||||
result = &health.HealthCheckResult{
|
result = new(health.HealthCheckResult)
|
||||||
Latency: time.Since(start),
|
|
||||||
}
|
|
||||||
if dialErr != nil {
|
if dialErr != nil {
|
||||||
result.Detail = dialErr.Error()
|
result.Detail = dialErr.Error()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
conn.Close()
|
defer conn.Close()
|
||||||
|
result.Latency = time.Since(start)
|
||||||
result.Healthy = true
|
result.Healthy = true
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue