summaryrefslogtreecommitdiff
path: root/modules/caddyhttp/reverseproxy/healthchecker.go
diff options
context:
space:
mode:
authorMatthew Holt <mholt@users.noreply.github.com>2019-05-04 10:49:50 -0600
committerMatthew Holt <mholt@users.noreply.github.com>2019-05-04 10:49:50 -0600
commit1136e2cfeed5cc06a0811d39c2560c06f9dd74a2 (patch)
treeccda533fe09e47e6058a049122d53e4879e5e77e /modules/caddyhttp/reverseproxy/healthchecker.go
parent5859cd8dad32fdd7ea55daa5e4377e273fb97a3e (diff)
Add reverse proxy
Diffstat (limited to 'modules/caddyhttp/reverseproxy/healthchecker.go')
-rwxr-xr-xmodules/caddyhttp/reverseproxy/healthchecker.go64
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,
+ }
+}