mirror of
https://github.com/caddyserver/caddy.git
synced 2025-01-14 23:06:27 +03:00
Merge pull request #1 from caddyserver/fix/goroutine-leak-healthchecker
fix goroutine leak in healthcheckers
This commit is contained in:
commit
8947ae0cc1
2 changed files with 14 additions and 6 deletions
|
@ -15,24 +15,32 @@ type HealthChecker struct {
|
||||||
upstream Upstream
|
upstream Upstream
|
||||||
Ticker *time.Ticker
|
Ticker *time.Ticker
|
||||||
HTTPClient *http.Client
|
HTTPClient *http.Client
|
||||||
|
StopChan chan bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// ScheduleChecks periodically runs health checks against an upstream host.
|
// ScheduleChecks periodically runs health checks against an upstream host.
|
||||||
func (h *HealthChecker) ScheduleChecks(url string) {
|
func (h *HealthChecker) ScheduleChecks(url string) {
|
||||||
// check if a host is healthy on start vs waiting for timer
|
// check if a host is healthy on start vs waiting for timer
|
||||||
h.upstream.SetHealthiness(h.IsHealthy(url))
|
h.upstream.SetHealthiness(h.IsHealthy(url))
|
||||||
|
stop := make(chan bool)
|
||||||
|
h.StopChan = stop
|
||||||
|
|
||||||
for {
|
go func() {
|
||||||
select {
|
for {
|
||||||
case <-h.Ticker.C:
|
select {
|
||||||
h.upstream.SetHealthiness(h.IsHealthy(url))
|
case <-h.Ticker.C:
|
||||||
|
h.upstream.SetHealthiness(h.IsHealthy(url))
|
||||||
|
case <-stop:
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop stops the healthchecker from makeing further requests.
|
// Stop stops the healthchecker from makeing further requests.
|
||||||
func (h *HealthChecker) Stop() {
|
func (h *HealthChecker) Stop() {
|
||||||
h.Ticker.Stop()
|
h.Ticker.Stop()
|
||||||
|
close(h.StopChan)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsHealthy attempts to check if a upstream host is healthy.
|
// IsHealthy attempts to check if a upstream host is healthy.
|
||||||
|
|
|
@ -140,7 +140,7 @@ func NewLoadBalancedReverseProxy(lb *LoadBalanced, ctx caddy2.Context) error {
|
||||||
// TODO :- if path is empty why does this empty the entire Target?
|
// TODO :- if path is empty why does this empty the entire Target?
|
||||||
// nu.Target.Path = uc.HealthCheckPath
|
// nu.Target.Path = uc.HealthCheckPath
|
||||||
|
|
||||||
go nu.healthChecker.ScheduleChecks(nu.Target.String())
|
nu.healthChecker.ScheduleChecks(nu.Target.String())
|
||||||
lb.HealthCheckers = append(lb.HealthCheckers, nu.healthChecker)
|
lb.HealthCheckers = append(lb.HealthCheckers, nu.healthChecker)
|
||||||
|
|
||||||
us = append(us, nu)
|
us = append(us, nu)
|
||||||
|
|
Loading…
Reference in a new issue