diff --git a/.changelog/13847.txt b/.changelog/13847.txt new file mode 100644 index 0000000000..2bbe7e241f --- /dev/null +++ b/.changelog/13847.txt @@ -0,0 +1,3 @@ +```release-note:bug +connect: Fixed a goroutine/memory leak that would occur when using the ingress gateway. +``` diff --git a/agent/proxycfg/ingress_gateway.go b/agent/proxycfg/ingress_gateway.go index 3fb67ddabc..3889bdba87 100644 --- a/agent/proxycfg/ingress_gateway.go +++ b/agent/proxycfg/ingress_gateway.go @@ -148,6 +148,16 @@ func (s *handlerIngressGateway) handleUpdate(ctx context.Context, u UpdateEvent, for uid, cancelFn := range snap.IngressGateway.WatchedDiscoveryChains { if _, ok := watchedSvcs[uid]; !ok { + for targetID, cancelUpstreamFn := range snap.IngressGateway.WatchedUpstreams[uid] { + s.logger.Debug("stopping watch of target", + "upstream", uid, + "target", targetID, + ) + delete(snap.IngressGateway.WatchedUpstreams[uid], targetID) + delete(snap.IngressGateway.WatchedUpstreamEndpoints[uid], targetID) + cancelUpstreamFn() + } + cancelFn() delete(snap.IngressGateway.WatchedDiscoveryChains, uid) } diff --git a/agent/proxycfg/upstreams.go b/agent/proxycfg/upstreams.go index a47510543c..600a89e092 100644 --- a/agent/proxycfg/upstreams.go +++ b/agent/proxycfg/upstreams.go @@ -436,7 +436,17 @@ type discoveryChainWatchOpts struct { } func (s *handlerUpstreams) watchDiscoveryChain(ctx context.Context, snap *ConfigSnapshot, opts discoveryChainWatchOpts) error { - if _, ok := snap.ConnectProxy.WatchedDiscoveryChains[opts.id]; ok { + var watchedDiscoveryChains map[UpstreamID]context.CancelFunc + switch s.kind { + case structs.ServiceKindIngressGateway: + watchedDiscoveryChains = snap.IngressGateway.WatchedDiscoveryChains + case structs.ServiceKindConnectProxy: + watchedDiscoveryChains = snap.ConnectProxy.WatchedDiscoveryChains + default: + return fmt.Errorf("unsupported kind %s", s.kind) + } + + if _, ok := watchedDiscoveryChains[opts.id]; ok { return nil } @@ -457,16 +467,7 @@ func (s *handlerUpstreams) watchDiscoveryChain(ctx context.Context, snap *Config return err } - switch s.kind { - case structs.ServiceKindIngressGateway: - snap.IngressGateway.WatchedDiscoveryChains[opts.id] = cancel - case structs.ServiceKindConnectProxy: - snap.ConnectProxy.WatchedDiscoveryChains[opts.id] = cancel - default: - cancel() - return fmt.Errorf("unsupported kind %s", s.kind) - } - + watchedDiscoveryChains[opts.id] = cancel return nil }