package monitor import ( "errors" "net" "net/url" "syscall" "time" "github.com/yusing/godoxy/internal/types" ) type ( RawHealthMonitor struct { *monitor dialer *net.Dialer } ) func NewRawHealthMonitor(url *url.URL, config types.HealthCheckConfig) *RawHealthMonitor { mon := new(RawHealthMonitor) mon.monitor = newMonitor(url, config, mon.CheckHealth) mon.dialer = &net.Dialer{ Timeout: config.Timeout, FallbackDelay: -1, } return mon } func (mon *RawHealthMonitor) CheckHealth() (types.HealthCheckResult, error) { ctx, cancel := mon.ContextWithTimeout("ping request timed out") defer cancel() url := mon.url.Load() start := time.Now() conn, err := mon.dialer.DialContext(ctx, url.Scheme, url.Host) lat := time.Since(start) if err != nil { if errors.Is(err, net.ErrClosed) || errors.Is(err, syscall.ECONNREFUSED) || errors.Is(err, syscall.ECONNRESET) || errors.Is(err, syscall.ECONNABORTED) || errors.Is(err, syscall.EPIPE) { return types.HealthCheckResult{ Latency: lat, Healthy: false, Detail: err.Error(), }, nil } return types.HealthCheckResult{}, err } defer conn.Close() return types.HealthCheckResult{ Latency: lat, Healthy: true, }, nil }