diff options
author | 2017-04-26 10:58:14 +0100 | |
---|---|---|
committer | 2017-04-26 10:58:14 +0100 | |
commit | 3b5b6a233fc669dfb47a6dc4eb8899c3e992cc32 (patch) | |
tree | 5db5d0834e2d3c6143387c3c96fe904782c1f5d9 /middleware/proxy/upstream.go | |
parent | 003b1bf678f6fc1d551fed5184adccde2137e86f (diff) | |
download | coredns-3b5b6a233fc669dfb47a6dc4eb8899c3e992cc32.tar.gz coredns-3b5b6a233fc669dfb47a6dc4eb8899c3e992cc32.tar.zst coredns-3b5b6a233fc669dfb47a6dc4eb8899c3e992cc32.zip |
middleware/proxy: Kill goroutines on stop (#646)
* middleware/proxy: Kill goroutines on stop
Ports caddy's https://github.com/mholt/caddy/commit/59bf71c2932c3b814a6a1211c492a1aa9f71d4a1
Excludes the proxy_test.go test part though.
Fixes #644
* Add tests
Diffstat (limited to '')
-rw-r--r-- | middleware/proxy/upstream.go | 26 |
1 files changed, 21 insertions, 5 deletions
diff --git a/middleware/proxy/upstream.go b/middleware/proxy/upstream.go index 278b08d0f..8bc3e5306 100644 --- a/middleware/proxy/upstream.go +++ b/middleware/proxy/upstream.go @@ -10,6 +10,7 @@ import ( "net/url" "strconv" "strings" + "sync" "sync/atomic" "time" @@ -25,7 +26,10 @@ var ( ) type staticUpstream struct { - from string + from string + stop chan struct{} // Signals running goroutines to stop. + wg sync.WaitGroup // Used to wait for running goroutines to stop. + Hosts HostPool Policy Policy Spray Policy @@ -49,6 +53,7 @@ func NewStaticUpstreams(c *caddyfile.Dispenser) ([]Upstream, error) { for c.Next() { upstream := &staticUpstream{ from: ".", + stop: make(chan struct{}), Hosts: nil, Policy: &Random{}, Spray: nil, @@ -108,13 +113,25 @@ func NewStaticUpstreams(c *caddyfile.Dispenser) ([]Upstream, error) { } if upstream.HealthCheck.Path != "" { - go upstream.HealthCheckWorker(nil) + upstream.wg.Add(1) + go func() { + defer upstream.wg.Done() + upstream.HealthCheckWorker(upstream.stop) + }() } upstreams = append(upstreams, upstream) } return upstreams, nil } +// Stop sends a signal to all goroutines started by this staticUpstream to exit +// and waits for them to finish before returning. +func (u *staticUpstream) Stop() error { + close(u.stop) + u.wg.Wait() + return nil +} + // RegisterPolicy adds a custom policy to the proxy. func RegisterPolicy(name string, policy func() Policy) { supportedPolicies[name] = policy @@ -281,9 +298,8 @@ func (u *staticUpstream) HealthCheckWorker(stop chan struct{}) { case <-ticker.C: u.healthCheck() case <-stop: - // TODO: the library should provide a stop channel and global - // waitgroup to allow goroutines started by plugins a chance - // to clean themselves up. + ticker.Stop() + return } } } |