diff options
author | Matthew Holt <mholt@users.noreply.github.com> | 2019-05-04 10:49:50 -0600 |
---|---|---|
committer | Matthew Holt <mholt@users.noreply.github.com> | 2019-05-04 10:49:50 -0600 |
commit | 1136e2cfeed5cc06a0811d39c2560c06f9dd74a2 (patch) | |
tree | ccda533fe09e47e6058a049122d53e4879e5e77e /modules/caddyhttp/reverseproxy/healthchecker.go | |
parent | 5859cd8dad32fdd7ea55daa5e4377e273fb97a3e (diff) |
Add reverse proxy
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, + } +} |