@@ -394,6 +394,9 @@ func (h *Handler) Cleanup() error {
394394
395395 // remove hosts from our config from the pool
396396 for _ , upstream := range h .Upstreams {
397+ if upstream .NumRequests () > 0 {
398+ upstream .fillInfilghtHost (upstream .NumRequests ())
399+ }
397400 _ , _ = hosts .Delete (upstream .String ())
398401 }
399402
@@ -458,8 +461,16 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyht
458461 }
459462
460463 var done bool
461- done , proxyErr = h .proxyLoopIteration (clonedReq , r , w , proxyErr , start , retries , repl , reqHeader , reqHost , next )
464+ done , dialInfo , proxyErr : = h .proxyLoopIteration (clonedReq , r , w , proxyErr , start , retries , repl , reqHeader , reqHost , next )
462465 if done {
466+ key := dialInfo .Address
467+ val := inflightHosts .Load (key )
468+ if val != nil {
469+ host , _ := val .(* Host )
470+ if host .NumRequests () <= 0 {
471+ _ , _ = inflightHosts .Delete (key )
472+ }
473+ }
463474 break
464475 }
465476 if h .VerboseLogs {
@@ -490,7 +501,7 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyht
490501// be assigned to the proxyErr value for the next iteration of the loop (or the error handled after break).
491502func (h * Handler ) proxyLoopIteration (r * http.Request , origReq * http.Request , w http.ResponseWriter , proxyErr error , start time.Time , retries int ,
492503 repl * caddy.Replacer , reqHeader http.Header , reqHost string , next caddyhttp.Handler ,
493- ) (bool , error ) {
504+ ) (bool , * DialInfo , error ) {
494505 // get the updated list of upstreams
495506 upstreams := h .Upstreams
496507 if h .DynamicUpstreams != nil {
@@ -524,17 +535,17 @@ func (h *Handler) proxyLoopIteration(r *http.Request, origReq *http.Request, w h
524535 proxyErr = caddyhttp .Error (http .StatusServiceUnavailable , errNoUpstream )
525536 }
526537 if ! h .LoadBalancing .tryAgain (h .ctx , start , retries , proxyErr , r , h .logger ) {
527- return true , proxyErr
538+ return true , nil , proxyErr
528539 }
529- return false , proxyErr
540+ return false , nil , proxyErr
530541 }
531542
532543 // the dial address may vary per-request if placeholders are
533544 // used, so perform those replacements here; the resulting
534545 // DialInfo struct should have valid network address syntax
535546 dialInfo , err := upstream .fillDialInfo (repl )
536547 if err != nil {
537- return true , fmt .Errorf ("making dial info: %v" , err )
548+ return true , nil , fmt .Errorf ("making dial info: %v" , err )
538549 }
539550
540551 if c := h .logger .Check (zapcore .DebugLevel , "selected upstream" ); c != nil {
@@ -574,26 +585,26 @@ func (h *Handler) proxyLoopIteration(r *http.Request, origReq *http.Request, w h
574585 if proxyErr == nil || errors .Is (proxyErr , context .Canceled ) {
575586 // context.Canceled happens when the downstream client
576587 // cancels the request, which is not our failure
577- return true , nil
588+ return true , & dialInfo , nil
578589 }
579590
580591 // if the roundtrip was successful, don't retry the request or
581592 // ding the health status of the upstream (an error can still
582593 // occur after the roundtrip if, for example, a response handler
583594 // after the roundtrip returns an error)
584595 if succ , ok := proxyErr .(roundtripSucceededError ); ok {
585- return true , succ .error
596+ return true , & dialInfo , succ .error
586597 }
587598
588599 // remember this failure (if enabled)
589600 h .countFailure (upstream )
590601
591602 // if we've tried long enough, break
592603 if ! h .LoadBalancing .tryAgain (h .ctx , start , retries , proxyErr , r , h .logger ) {
593- return true , proxyErr
604+ return true , & dialInfo , proxyErr
594605 }
595606
596- return false , proxyErr
607+ return false , & dialInfo , proxyErr
597608}
598609
599610// Mapping of the canonical form of the headers, to the RFC 6455 form,
@@ -829,8 +840,14 @@ func (h Handler) addForwardedHeaders(req *http.Request) error {
829840func (h * Handler ) reverseProxy (rw http.ResponseWriter , req * http.Request , origReq * http.Request , repl * caddy.Replacer , di DialInfo , next caddyhttp.Handler ) error {
830841 _ = di .Upstream .Host .countRequest (1 )
831842 //nolint:errcheck
832- defer di .Upstream .Host .countRequest (- 1 )
833-
843+ defer func () {
844+ di .Upstream .Host .countRequest (- 1 )
845+ inflightHost := inflightHosts .Load (di .Address )
846+ if inflightHost != nil {
847+ host , _ := inflightHost .(* Host )
848+ host .countRequest (- 1 )
849+ }
850+ }()
834851 // point the request to this upstream
835852 h .directRequest (req , di )
836853
0 commit comments