From c8b8c3a7b2ee630a4a8ac4c42afdf41169ba36b4 Mon Sep 17 00:00:00 2001
From: Francis Lavoie <lavofr@gmail.com>
Date: Sun, 26 Feb 2023 02:16:05 -0500
Subject: [PATCH] Add `min_success_ratio` WIP

---
 modules/caddyhttp/reverseproxy/caddyfile.go    | 17 +++++++++++++++++
 modules/caddyhttp/reverseproxy/healthchecks.go |  5 +++++
 2 files changed, 22 insertions(+)

diff --git a/modules/caddyhttp/reverseproxy/caddyfile.go b/modules/caddyhttp/reverseproxy/caddyfile.go
index 4f27ca1ef..c12fb2ec0 100644
--- a/modules/caddyhttp/reverseproxy/caddyfile.go
+++ b/modules/caddyhttp/reverseproxy/caddyfile.go
@@ -78,6 +78,7 @@ func parseCaddyfile(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, error)
 //	    fail_duration     <duration>
 //	    max_fails         <num>
 //	    success_duration  <duration>
+//	    min_success_ratio <ratio>
 //	    unhealthy_status  <status>
 //	    unhealthy_latency <duration>
 //	    unhealthy_request_count <num>
@@ -439,6 +440,22 @@ func (h *Handler) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
 				}
 				h.HealthChecks.Passive.SuccessDuration = caddy.Duration(dur)
 
+			case "min_success_ratio":
+				if !d.NextArg() {
+					return d.ArgErr()
+				}
+				if h.HealthChecks == nil {
+					h.HealthChecks = new(HealthChecks)
+				}
+				if h.HealthChecks.Passive == nil {
+					h.HealthChecks.Passive = new(PassiveHealthChecks)
+				}
+				ratio, err := caddyhttp.ParseRatio(d.Val())
+				if err != nil {
+					return d.Errf("bad ratio value '%s': %v", d.Val(), err)
+				}
+				h.HealthChecks.Passive.MinSuccessRatio = ratio
+
 			case "fail_duration":
 				if !d.NextArg() {
 					return d.ArgErr()
diff --git a/modules/caddyhttp/reverseproxy/healthchecks.go b/modules/caddyhttp/reverseproxy/healthchecks.go
index 1362afa89..20ba0b9bf 100644
--- a/modules/caddyhttp/reverseproxy/healthchecks.go
+++ b/modules/caddyhttp/reverseproxy/healthchecks.go
@@ -122,6 +122,11 @@ type PassiveHealthChecks struct {
 	// How long to remember a successful request to a backend. Default is 0.
 	SuccessDuration caddy.Duration `json:"success_duration,omitempty"`
 
+	// The minimum ratio of successful to failed requests necessary to
+	// consider a backend as healthy. Both fail and success durations
+	// must be configured for those stats to be counted. Default is 0 (no ratio).
+	MinSuccessRatio caddyhttp.Ratio `json:"min_success_ratio,omitempty"`
+
 	// Limits the number of simultaneous requests to a backend by
 	// marking the backend as "down" if it has this many concurrent
 	// requests or more.