Skip to content

Commit c96b18f

Browse files
committed
use lru cache to cleanup
1 parent 0b14b44 commit c96b18f

File tree

1 file changed

+33
-32
lines changed

1 file changed

+33
-32
lines changed

projects/gateway2/status/status_syncer.go

Lines changed: 33 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77

88
"github.com/solo-io/go-utils/contextutils"
99
"k8s.io/apimachinery/pkg/types"
10+
"k8s.io/utils/lru"
1011

1112
"github.com/solo-io/gloo/projects/gateway2/proxy_syncer"
1213
gwplugins "github.com/solo-io/gloo/projects/gateway2/translator/plugins"
@@ -39,22 +40,22 @@ type GatewayStatusSyncer interface {
3940
type statusSyncerFactory struct {
4041
// maps a proxy sync action to the plugin registry that produced it
4142
// sync iteration -> plugin registry
42-
registryPerSync map[int]*registry.PluginRegistry
43+
registryPerSyncCache *lru.Cache // map[int]*registry.PluginRegistry
4344
// maps a proxy to the sync iteration that produced it
4445
// only the latest sync iteration is stored and used to apply status plugins
4546
resyncsPerProxy map[types.NamespacedName]int
4647
// proxies left to sync
47-
resyncsPerIteration map[int][]types.NamespacedName
48-
49-
lock *sync.Mutex
48+
resyncsPerIterationCache *lru.Cache // map[int][]types.NamespacedName
49+
lock *sync.Mutex
5050
}
5151

5252
func NewStatusSyncerFactory() GatewayStatusSyncer {
5353
return &statusSyncerFactory{
54-
registryPerSync: make(map[int]*registry.PluginRegistry),
55-
resyncsPerProxy: make(map[types.NamespacedName]int),
56-
resyncsPerIteration: make(map[int][]types.NamespacedName),
57-
lock: &sync.Mutex{},
54+
// Set a max value of 3 for n-2 iterations. Ideally we should only care about n-1 but playing it safe
55+
registryPerSyncCache: lru.New(3),
56+
resyncsPerIterationCache: lru.New(3),
57+
resyncsPerProxy: make(map[types.NamespacedName]int),
58+
lock: &sync.Mutex{},
5859
}
5960
}
6061

@@ -70,21 +71,20 @@ func (f *statusSyncerFactory) QueueStatusForProxies(
7071

7172
contextutils.LoggerFrom(ctx).Debugf("queueing %v proxies for sync %d", len(proxiesToQueue), totalSyncCount)
7273

74+
resyncsPerIteration := make([]types.NamespacedName, len(proxiesToQueue))
7375
// queue each proxy for a given sync iteration
7476
for _, proxy := range proxiesToQueue {
7577
proxyKey := getProxyNameNamespace(proxy)
7678
// overwrite the sync count for the proxy with the most recent sync count
7779
f.resyncsPerProxy[proxyKey] = totalSyncCount
7880

7981
// keep track of proxies to check all proxies are handled in debugger
80-
f.resyncsPerIteration[totalSyncCount] = append(f.resyncsPerIteration[totalSyncCount], proxyKey)
82+
resyncsPerIteration = append(resyncsPerIteration, proxyKey)
8183
}
84+
f.resyncsPerIterationCache.Add(totalSyncCount, resyncsPerIteration)
8285

8386
// the plugin registry that produced the proxies is the same for all proxies in a given sync
84-
f.registryPerSync[totalSyncCount] = pluginRegistry
85-
86-
delete(f.resyncsPerIteration, totalSyncCount-2)
87-
delete(f.registryPerSync, totalSyncCount-2)
87+
f.registryPerSyncCache.Add(totalSyncCount, pluginRegistry)
8888
}
8989

9090
// HandleProxyReports is a callback that applies status plugins to the proxies that have been queued
@@ -113,39 +113,40 @@ func (f *statusSyncerFactory) HandleProxyReports(ctx context.Context, proxiesWit
113113
continue
114114
}
115115

116-
if len(f.resyncsPerIteration[proxySyncCount]) == 0 {
117-
// remove the key so the map does not indefinitely grow
118-
delete(f.resyncsPerIteration, proxySyncCount)
119-
// re-sync already happened, nothing to do
116+
// If the proxy does not exist in the cache, or the cache is empty, the re-sync already happened, nothing to do
117+
resyncsPerIterationIface, ok := f.resyncsPerIterationCache.Get(proxySyncCount)
118+
if !ok {
120119
continue
121-
} else {
122-
updatedList := make([]types.NamespacedName, 0)
123-
for _, proxyNameNs := range f.resyncsPerIteration[proxySyncCount] {
124-
if proxyNameNs != proxyKey {
125-
updatedList = append(updatedList, proxyNameNs)
126-
}
127-
}
128-
f.resyncsPerIteration[proxySyncCount] = updatedList
120+
}
121+
resyncsPerIteration := resyncsPerIterationIface.([]types.NamespacedName)
122+
if len(resyncsPerIteration) == 0 {
123+
f.resyncsPerIterationCache.Remove(proxySyncCount)
124+
continue
125+
}
129126

130-
if len(f.resyncsPerIteration[proxySyncCount]) == 0 {
131-
// remove the key so the map does not indefinitely grow
132-
delete(f.resyncsPerIteration, proxySyncCount)
127+
updatedList := make([]types.NamespacedName, 0)
128+
for _, proxyNameNs := range resyncsPerIteration {
129+
if proxyNameNs != proxyKey {
130+
updatedList = append(updatedList, proxyNameNs)
133131
}
134132
}
133+
f.resyncsPerIterationCache.Add(proxySyncCount, updatedList)
135134

136135
proxiesToReport[proxySyncCount] = append(proxiesToReport[proxySyncCount], proxyWithReport)
137136
// remove the proxy from the queue
138137
delete(f.resyncsPerProxy, proxyKey)
139138
}
140139

141140
for syncCount, proxies := range proxiesToReport {
142-
if plugins, ok := f.registryPerSync[syncCount]; ok {
143-
newStatusSyncer(plugins).applyStatusPlugins(ctx, proxies)
141+
if plugins, ok := f.registryPerSyncCache.Get(syncCount); ok {
142+
newStatusSyncer(plugins.(*registry.PluginRegistry)).applyStatusPlugins(ctx, proxies)
144143
}
145144

146145
// If there are no more proxies for the sync iteration, delete the sync count
147-
if len(f.resyncsPerIteration[syncCount]) == 0 {
148-
delete(f.registryPerSync, syncCount)
146+
resyncsPerIterationIface, _ := f.resyncsPerIterationCache.Get(syncCount)
147+
resyncsPerIteration := resyncsPerIterationIface.([]types.NamespacedName)
148+
if len(resyncsPerIteration) == 0 {
149+
f.registryPerSyncCache.Remove(syncCount)
149150
}
150151
}
151152
}

0 commit comments

Comments
 (0)