Skip to content

Commit 71a0bfc

Browse files
authored
fix for concurrent read and write and in buildInformerAndNamespaceList (#5671)
1 parent 6c7d30e commit 71a0bfc

File tree

2 files changed

+29
-47
lines changed

2 files changed

+29
-47
lines changed

pkg/k8s/informer/K8sInformerFactory.go

Lines changed: 27 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -18,25 +18,23 @@ package informer
1818

1919
import (
2020
"github.com/devtron-labs/common-lib/utils/k8s"
21-
"sync"
22-
"time"
23-
2421
"github.com/devtron-labs/devtron/api/bean"
2522
"go.uber.org/zap"
2623
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2724
kubeinformers "k8s.io/client-go/informers"
2825
"k8s.io/client-go/tools/cache"
26+
"sync"
27+
"time"
2928
)
3029

31-
func NewGlobalMapClusterNamespace() map[string]map[string]bool {
32-
globalMapClusterNamespace := make(map[string]map[string]bool)
30+
func NewGlobalMapClusterNamespace() sync.Map {
31+
var globalMapClusterNamespace sync.Map
3332
return globalMapClusterNamespace
3433
}
3534

3635
type K8sInformerFactoryImpl struct {
3736
logger *zap.SugaredLogger
38-
globalMapClusterNamespace map[string]map[string]bool // {"cluster1":{"ns1":true","ns2":true"}}
39-
mutex sync.Mutex
37+
globalMapClusterNamespace sync.Map // {"cluster1":{"ns1":true","ns2":true"}}
4038
informerStopper map[string]chan struct{}
4139
k8sUtil *k8s.K8sServiceImpl
4240
}
@@ -47,7 +45,7 @@ type K8sInformerFactory interface {
4745
CleanNamespaceInformer(clusterName string)
4846
}
4947

50-
func NewK8sInformerFactoryImpl(logger *zap.SugaredLogger, globalMapClusterNamespace map[string]map[string]bool, k8sUtil *k8s.K8sServiceImpl) *K8sInformerFactoryImpl {
48+
func NewK8sInformerFactoryImpl(logger *zap.SugaredLogger, globalMapClusterNamespace sync.Map, k8sUtil *k8s.K8sServiceImpl) *K8sInformerFactoryImpl {
5149
informerFactory := &K8sInformerFactoryImpl{
5250
logger: logger,
5351
globalMapClusterNamespace: globalMapClusterNamespace,
@@ -59,19 +57,17 @@ func NewK8sInformerFactoryImpl(logger *zap.SugaredLogger, globalMapClusterNamesp
5957

6058
func (impl *K8sInformerFactoryImpl) GetLatestNamespaceListGroupByCLuster() map[string]map[string]bool {
6159
copiedClusterNamespaces := make(map[string]map[string]bool)
62-
for key, value := range impl.globalMapClusterNamespace {
63-
for namespace, v := range value {
64-
if _, ok := copiedClusterNamespaces[key]; !ok {
65-
allNamespaces := make(map[string]bool)
66-
allNamespaces[namespace] = v
67-
copiedClusterNamespaces[key] = allNamespaces
68-
} else {
69-
allNamespaces := copiedClusterNamespaces[key]
70-
allNamespaces[namespace] = v
71-
copiedClusterNamespaces[key] = allNamespaces
72-
}
73-
}
74-
}
60+
impl.globalMapClusterNamespace.Range(func(key, value interface{}) bool {
61+
clusterName := key.(string)
62+
allNamespaces := value.(*sync.Map)
63+
namespaceMap := make(map[string]bool)
64+
allNamespaces.Range(func(nsKey, nsValue interface{}) bool {
65+
namespaceMap[nsKey.(string)] = nsValue.(bool)
66+
return true
67+
})
68+
copiedClusterNamespaces[clusterName] = namespaceMap
69+
return true
70+
})
7571
return copiedClusterNamespaces
7672
}
7773

@@ -86,14 +82,14 @@ func (impl *K8sInformerFactoryImpl) BuildInformer(clusterInfo []*bean.ClusterInf
8682
CertData: info.CertData,
8783
CAData: info.CAData,
8884
}
89-
impl.buildInformerAndNamespaceList(info.ClusterName, clusterConfig, &impl.mutex)
85+
impl.buildInformerAndNamespaceList(info.ClusterName, clusterConfig)
9086
}
9187
return
9288
}
9389

94-
func (impl *K8sInformerFactoryImpl) buildInformerAndNamespaceList(clusterName string, clusterConfig *k8s.ClusterConfig, mutex *sync.Mutex) map[string]map[string]bool {
95-
allNamespaces := make(map[string]bool)
96-
impl.globalMapClusterNamespace[clusterName] = allNamespaces
90+
func (impl *K8sInformerFactoryImpl) buildInformerAndNamespaceList(clusterName string, clusterConfig *k8s.ClusterConfig) sync.Map {
91+
allNamespaces := sync.Map{}
92+
impl.globalMapClusterNamespace.Store(clusterName, &allNamespaces)
9793
_, _, clusterClient, err := impl.k8sUtil.GetK8sConfigAndClients(clusterConfig)
9894
if err != nil {
9995
impl.logger.Errorw("error in getting k8s clientset", "err", err, "clusterName", clusterConfig.ClusterName)
@@ -105,30 +101,16 @@ func (impl *K8sInformerFactoryImpl) buildInformerAndNamespaceList(clusterName st
105101
nsInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
106102
AddFunc: func(obj interface{}) {
107103
if mobject, ok := obj.(metav1.Object); ok {
108-
mutex.Lock()
109-
defer mutex.Unlock()
110-
if _, ok := impl.globalMapClusterNamespace[clusterName]; !ok {
111-
allNamespaces := make(map[string]bool)
112-
allNamespaces[mobject.GetName()] = true
113-
impl.globalMapClusterNamespace[clusterName] = allNamespaces
114-
} else {
115-
allNamespaces := impl.globalMapClusterNamespace[clusterName]
116-
allNamespaces[mobject.GetName()] = true
117-
impl.globalMapClusterNamespace[clusterName] = allNamespaces
118-
}
119-
//mutex.Unlock()
104+
value, _ := impl.globalMapClusterNamespace.Load(clusterName)
105+
allNamespaces := value.(*sync.Map)
106+
allNamespaces.Store(mobject.GetName(), true)
120107
}
121108
},
122109
DeleteFunc: func(obj interface{}) {
123110
if object, ok := obj.(metav1.Object); ok {
124-
mutex.Lock()
125-
defer mutex.Unlock()
126-
if _, ok := impl.globalMapClusterNamespace[clusterName]; ok {
127-
allNamespaces := impl.globalMapClusterNamespace[clusterName]
128-
delete(allNamespaces, object.GetName())
129-
impl.globalMapClusterNamespace[clusterName] = allNamespaces
130-
//mutex.Unlock()
131-
}
111+
value, _ := impl.globalMapClusterNamespace.Load(clusterName)
112+
allNamespaces := value.(*sync.Map)
113+
allNamespaces.Delete(object.GetName())
132114
}
133115
},
134116
})

wire_gen.go

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)