Skip to content

Commit 8c72255

Browse files
authored
[1.17] fix memory leak (#10639)
1 parent c0b3907 commit 8c72255

File tree

2 files changed

+26
-4
lines changed

2 files changed

+26
-4
lines changed

changelog/v1.17.25/fix-mem-lk.yaml

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
changelog:
2+
- type: FIX
3+
issueLink: https://github.com/solo-io/solo-projects/issues/7805
4+
resolvesIssue: false
5+
description: Fixes a memory leak caused by an indefinitely growing map
6+

projects/gateway2/status/status_syncer.go

+20-4
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,23 @@ func (f *statusSyncerFactory) QueueStatusForProxies(
7272

7373
// queue each proxy for a given sync iteration
7474
for _, proxy := range proxiesToQueue {
75+
proxyKey := getProxyNameNamespace(proxy)
7576
// overwrite the sync count for the proxy with the most recent sync count
76-
f.resyncsPerProxy[getProxyNameNamespace(proxy)] = totalSyncCount
77+
f.resyncsPerProxy[proxyKey] = totalSyncCount
7778

7879
// keep track of proxies to check all proxies are handled in debugger
79-
f.resyncsPerIteration[totalSyncCount] = append(f.resyncsPerIteration[totalSyncCount], getProxyNameNamespace(proxy))
80+
f.resyncsPerIteration[totalSyncCount] = append(f.resyncsPerIteration[totalSyncCount], proxyKey)
8081
}
82+
8183
// the plugin registry that produced the proxies is the same for all proxies in a given sync
8284
f.registryPerSync[totalSyncCount] = pluginRegistry
85+
86+
// Set a max value of 5 for n-5 iterations. Ideally we should only care about n-1 but playing it safe.
87+
// QueueStatusForProxies sets the entries in these maps, however the `proxy_sync_id` annotation on the proxy
88+
// (which is used as the map key) can change between when this method and HandleProxyReports is called.
89+
// This can result in the map indefinitely growing which is what the subsequent lines aim to stem.
90+
delete(f.resyncsPerIteration, totalSyncCount-5)
91+
delete(f.registryPerSync, totalSyncCount-5)
8392
}
8493

8594
// HandleProxyReports is a callback that applies status plugins to the proxies that have been queued
@@ -108,7 +117,9 @@ func (f *statusSyncerFactory) HandleProxyReports(ctx context.Context, proxiesWit
108117
continue
109118
}
110119

111-
if f.resyncsPerIteration[proxySyncCount] == nil {
120+
if len(f.resyncsPerIteration[proxySyncCount]) == 0 {
121+
// remove the key so the map does not indefinitely grow
122+
delete(f.resyncsPerIteration, proxySyncCount)
112123
// re-sync already happened, nothing to do
113124
continue
114125
} else {
@@ -119,6 +130,11 @@ func (f *statusSyncerFactory) HandleProxyReports(ctx context.Context, proxiesWit
119130
}
120131
}
121132
f.resyncsPerIteration[proxySyncCount] = updatedList
133+
134+
if len(f.resyncsPerIteration[proxySyncCount]) == 0 {
135+
// remove the key so the map does not indefinitely grow
136+
delete(f.resyncsPerIteration, proxySyncCount)
137+
}
122138
}
123139

124140
proxiesToReport[proxySyncCount] = append(proxiesToReport[proxySyncCount], proxyWithReport)
@@ -132,7 +148,7 @@ func (f *statusSyncerFactory) HandleProxyReports(ctx context.Context, proxiesWit
132148
}
133149

134150
// If there are no more proxies for the sync iteration, delete the sync count
135-
if len(f.resyncsPerIteration) == 0 {
151+
if len(f.resyncsPerIteration[syncCount]) == 0 {
136152
delete(f.registryPerSync, syncCount)
137153
}
138154
}

0 commit comments

Comments
 (0)