diff options
Diffstat (limited to 'modules/caddyhttp/reverseproxy/healthchecker.go')
-rwxr-xr-x | modules/caddyhttp/reverseproxy/healthchecker.go | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/modules/caddyhttp/reverseproxy/healthchecker.go b/modules/caddyhttp/reverseproxy/healthchecker.go new file mode 100755 index 0000000..add3aa0 --- /dev/null +++ b/modules/caddyhttp/reverseproxy/healthchecker.go @@ -0,0 +1,64 @@ +package reverseproxy + +import ( + "net/http" + "time" +) + +// Upstream represents the interface that must be satisfied to use the healthchecker. +type Upstream interface { + SetHealthiness(bool) +} + +// HealthChecker represents a worker that periodically evaluates if proxy upstream host is healthy. +type HealthChecker struct { + upstream Upstream + Ticker *time.Ticker + HTTPClient *http.Client +} + +// ScheduleChecks periodically runs health checks against an upstream host. +func (h *HealthChecker) ScheduleChecks(url string) { + // check if a host is healthy on start vs waiting for timer + h.upstream.SetHealthiness(h.IsHealthy(url)) + + for { + select { + case <-h.Ticker.C: + h.upstream.SetHealthiness(h.IsHealthy(url)) + } + } +} + +// Stop stops the healthchecker from makeing further requests. +func (h *HealthChecker) Stop() { + h.Ticker.Stop() +} + +// IsHealthy attempts to check if a upstream host is healthy. +func (h *HealthChecker) IsHealthy(url string) bool { + req, err := http.NewRequest(http.MethodGet, url, nil) + if err != nil { + return false + } + + resp, err := h.HTTPClient.Do(req) + if err != nil { + return false + } + + if resp.StatusCode < 200 || resp.StatusCode >= 400 { + return false + } + + return true +} + +// NewHealthCheckWorker returns a new instance of a HealthChecker. +func NewHealthCheckWorker(u Upstream, interval time.Duration, client *http.Client) *HealthChecker { + return &HealthChecker{ + upstream: u, + Ticker: time.NewTicker(interval), + HTTPClient: client, + } +} |