Commit 681d1530 authored by Marcin Wielgus's avatar Marcin Wielgus

Fix deadlock possibility in federated informer

parent 214c9160
...@@ -344,8 +344,6 @@ func (f *federatedInformerImpl) getReadyClusterUnlocked(name string) (*federatio ...@@ -344,8 +344,6 @@ func (f *federatedInformerImpl) getReadyClusterUnlocked(name string) (*federatio
// Synced returns true if the view is synced (for the first time) // Synced returns true if the view is synced (for the first time)
func (f *federatedInformerImpl) ClustersSynced() bool { func (f *federatedInformerImpl) ClustersSynced() bool {
f.Lock()
defer f.Unlock()
return f.clusterInformer.controller.HasSynced() return f.clusterInformer.controller.HasSynced()
} }
...@@ -452,18 +450,31 @@ func (fs *federatedStoreImpl) GetKeyFor(item interface{}) string { ...@@ -452,18 +450,31 @@ func (fs *federatedStoreImpl) GetKeyFor(item interface{}) string {
// Checks whether stores for all clusters form the lists (and only these) are there and // Checks whether stores for all clusters form the lists (and only these) are there and
// are synced. // are synced.
func (fs *federatedStoreImpl) ClustersSynced(clusters []*federation_api.Cluster) bool { func (fs *federatedStoreImpl) ClustersSynced(clusters []*federation_api.Cluster) bool {
// Get the list of informers to check under a lock and check it outside.
okSoFar, informersToCheck := func() (bool, []informer) {
fs.federatedInformer.Lock() fs.federatedInformer.Lock()
defer fs.federatedInformer.Unlock() defer fs.federatedInformer.Unlock()
if len(fs.federatedInformer.targetInformers) != len(clusters) { if len(fs.federatedInformer.targetInformers) != len(clusters) {
return false return false, []informer{}
} }
informersToCheck := make([]informer, 0, len(clusters))
for _, cluster := range clusters { for _, cluster := range clusters {
if targetInformer, found := fs.federatedInformer.targetInformers[cluster.Name]; found { if targetInformer, found := fs.federatedInformer.targetInformers[cluster.Name]; found {
if !targetInformer.controller.HasSynced() { informersToCheck = append(informersToCheck, targetInformer)
} else {
return false, []informer{}
}
}
return true, informersToCheck
}()
if !okSoFar {
return false return false
} }
} else { for _, informerToCheck := range informersToCheck {
if !informerToCheck.controller.HasSynced() {
return false return false
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment