Skip to content

Commit f279152

Browse files
AwesomePatrolk8s-publishing-bot
authored andcommitted
Limit ResourceQuota LIST requests to times when informer is not synced
This should reduce the number of slow (100ms) LIST requests when there are no ResourceQuota objects present in the namespace. The behavior stays virtually the same. Kubernetes-commit: 1ac9e213a8dcd23e706f112f2dc3f8447eee33c9
1 parent a85a34b commit f279152

File tree

3 files changed

+13
-3
lines changed

3 files changed

+13
-3
lines changed

pkg/admission/plugin/resourcequota/admission.go

+6-1
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,9 @@ func (a *QuotaAdmission) SetExternalKubeClientSet(client kubernetes.Interface) {
114114

115115
// SetExternalKubeInformerFactory registers an informer factory into QuotaAdmission
116116
func (a *QuotaAdmission) SetExternalKubeInformerFactory(f informers.SharedInformerFactory) {
117-
a.quotaAccessor.lister = f.Core().V1().ResourceQuotas().Lister()
117+
quotas := f.Core().V1().ResourceQuotas()
118+
a.quotaAccessor.lister = quotas.Lister()
119+
a.quotaAccessor.hasSynced = quotas.Informer().HasSynced
118120
}
119121

120122
// SetQuotaConfiguration assigns and initializes configuration and evaluator for QuotaAdmission
@@ -144,6 +146,9 @@ func (a *QuotaAdmission) ValidateInitialization() error {
144146
if a.quotaAccessor.lister == nil {
145147
return fmt.Errorf("missing quotaAccessor.lister")
146148
}
149+
if a.quotaAccessor.hasSynced == nil {
150+
return fmt.Errorf("missing quotaAccessor.hasSynced")
151+
}
147152
if a.quotaConfiguration == nil {
148153
return fmt.Errorf("missing quotaConfiguration")
149154
}

pkg/admission/plugin/resourcequota/resource_access.go

+5-2
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ type quotaAccessor struct {
4848
// lister can list/get quota objects from a shared informer's cache
4949
lister corev1listers.ResourceQuotaLister
5050

51+
// hasSynced indicates whether the lister has completed its initial sync
52+
hasSynced func() bool
53+
5154
// liveLookups holds the last few live lookups we've done to help ammortize cost on repeated lookup failures.
5255
// This lets us handle the case of latent caches, by looking up actual results for a namespace on cache miss/no results.
5356
// We track the lookup result here so that for repeated requests, we don't look it up very often.
@@ -112,8 +115,8 @@ func (e *quotaAccessor) GetQuotas(namespace string) ([]corev1.ResourceQuota, err
112115
return nil, fmt.Errorf("error resolving quota: %v", err)
113116
}
114117

115-
// if there are no items held in our indexer, check our live-lookup LRU, if that misses, do the live lookup to prime it.
116-
if len(items) == 0 {
118+
// if there are no items held in our unsynced lister, check our live-lookup LRU, if that misses, do the live lookup to prime it.
119+
if len(items) == 0 && !e.hasSynced() {
117120
lruItemObj, ok := e.liveLookupCache.Get(namespace)
118121
if !ok || lruItemObj.(liveLookupEntry).expiry.Before(time.Now()) {
119122
// use singleflight.Group to avoid flooding the apiserver with repeated

pkg/admission/plugin/resourcequota/resource_access_test.go

+2
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ func TestLRUCacheLookup(t *testing.T) {
9797
accessor, _ := newQuotaAccessor()
9898
accessor.client = kubeClient
9999
accessor.lister = informerFactory.Core().V1().ResourceQuotas().Lister()
100+
accessor.hasSynced = func() bool { return false }
100101
accessor.liveLookupCache = liveLookupCache
101102

102103
for _, q := range tc.cacheInput {
@@ -151,6 +152,7 @@ func TestGetQuotas(t *testing.T) {
151152
accessor, _ := newQuotaAccessor()
152153
accessor.client = kubeClient
153154
accessor.lister = informerFactory.Core().V1().ResourceQuotas().Lister()
155+
accessor.hasSynced = func() bool { return false }
154156

155157
kubeClient.AddReactor("list", "resourcequotas", func(action core.Action) (bool, runtime.Object, error) {
156158
switch action.GetNamespace() {

0 commit comments

Comments
 (0)