Skip to content

Commit 3ff577c

Browse files
authored
Merge pull request #6602 from XiShanYongYe-Chang/wair-for-cache-in-ConfigurableInterpreter
Ensure configManager waits for informer cache sync before reporting as synced in ConfigurableInterpreter
2 parents bd7d74c + b7b1d9e commit 3ff577c

File tree

2 files changed

+394
-19
lines changed

2 files changed

+394
-19
lines changed

pkg/resourceinterpreter/customized/declarative/configmanager/manager.go

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,12 @@ limitations under the License.
1717
package configmanager
1818

1919
import (
20-
"fmt"
20+
"errors"
2121
"sort"
2222
"sync/atomic"
2323

2424
"k8s.io/apimachinery/pkg/labels"
2525
"k8s.io/apimachinery/pkg/runtime/schema"
26-
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
2726
"k8s.io/client-go/tools/cache"
2827
"k8s.io/klog/v2"
2928

@@ -49,6 +48,7 @@ type ConfigManager interface {
4948
// interpreterConfigManager collects the resource interpreter customization.
5049
type interpreterConfigManager struct {
5150
initialSynced atomic.Bool
51+
informer genericmanager.SingleClusterInformerManager
5252
lister cache.GenericLister
5353
configuration atomic.Value
5454
}
@@ -64,16 +64,12 @@ func (configManager *interpreterConfigManager) HasSynced() bool {
6464
return true
6565
}
6666

67-
if configuration, err := configManager.lister.List(labels.Everything()); err == nil && len(configuration) == 0 {
68-
// the empty list we initially stored is valid to use.
69-
// Setting initialSynced to true, so subsequent checks
70-
// would be able to take the fast path on the atomic boolean in a
71-
// cluster without any customization configured.
72-
configManager.initialSynced.Store(true)
73-
// the informer has synced, and we don't have any items
74-
return true
67+
err := configManager.updateConfiguration()
68+
if err != nil {
69+
klog.ErrorS(err, "error updating configuration")
70+
return false
7571
}
76-
return false
72+
return true
7773
}
7874

7975
// NewInterpreterConfigManager watches ResourceInterpreterCustomization and organizes
@@ -84,35 +80,48 @@ func NewInterpreterConfigManager(informer genericmanager.SingleClusterInformerMa
8480

8581
// In interpret command, rules are not loaded from server, so we don't start informer for it.
8682
if informer != nil {
83+
manager.informer = informer
8784
manager.lister = informer.Lister(resourceInterpreterCustomizationsGVR)
8885
configHandlers := fedinformer.NewHandlerOnEvents(
89-
func(_ interface{}) { manager.updateConfiguration() },
90-
func(_, _ interface{}) { manager.updateConfiguration() },
91-
func(_ interface{}) { manager.updateConfiguration() })
86+
func(_ interface{}) { _ = manager.updateConfiguration() },
87+
func(_, _ interface{}) { _ = manager.updateConfiguration() },
88+
func(_ interface{}) { _ = manager.updateConfiguration() })
9289
informer.ForResource(resourceInterpreterCustomizationsGVR, configHandlers)
9390
}
9491

9592
return manager
9693
}
9794

98-
func (configManager *interpreterConfigManager) updateConfiguration() {
95+
// updateConfiguration is used as the event handler for the ResourceInterpreterCustomization resource.
96+
// Any changes (add, update, delete) to these resources will trigger this method, which loads all
97+
// ResourceInterpreterCustomization resources and refreshes the internal cache accordingly.
98+
// Note: During startup, some events may be missed if the informer has not yet synced. If all events
99+
// are missed during startup, updateConfiguration will be called when HasSynced() is invoked for the
100+
// first time, ensuring the cache is updated on first use.
101+
func (configManager *interpreterConfigManager) updateConfiguration() error {
102+
if configManager.informer == nil {
103+
return errors.New("informer manager is not configured")
104+
}
105+
if !configManager.informer.IsInformerSynced(resourceInterpreterCustomizationsGVR) {
106+
return errors.New("informer of ResourceInterpreterCustomization not synced")
107+
}
108+
99109
configurations, err := configManager.lister.List(labels.Everything())
100110
if err != nil {
101-
utilruntime.HandleError(fmt.Errorf("error updating configuration: %v", err))
102-
return
111+
return err
103112
}
104113

105114
configs := make([]*configv1alpha1.ResourceInterpreterCustomization, len(configurations))
106115
for index, c := range configurations {
107116
config := &configv1alpha1.ResourceInterpreterCustomization{}
108117
if err = helper.ConvertToTypedObject(c, config); err != nil {
109-
klog.Errorf("Failed to transform ResourceInterpreterCustomization: %v", err)
110-
return
118+
return err
111119
}
112120
configs[index] = config
113121
}
114122

115123
configManager.LoadConfig(configs)
124+
return nil
116125
}
117126

118127
func (configManager *interpreterConfigManager) LoadConfig(configs []*configv1alpha1.ResourceInterpreterCustomization) {

0 commit comments

Comments
 (0)