Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e073148

Browse files
authored
Merge pull request kubernetes#125713 from pacoxu/revert-125405-upstream-consistent-read-from-cache-supports-pagination
Revert "apiserver/storage/cacher: consistent read from cache supports limit"
2 parents 01f9712 + df17ea2 commit e073148

File tree

3 files changed

+11
-96
lines changed

3 files changed

+11
-96
lines changed

staging/src/k8s.io/apiserver/pkg/storage/cacher/cacher.go

Lines changed: 6 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -768,26 +768,12 @@ func shouldDelegateList(opts storage.ListOptions) bool {
768768
consistentReadFromStorage := resourceVersion == "" && !(consistentListFromCacheEnabled && requestWatchProgressSupported)
769769
// Watch cache doesn't support continuations, so serve them from etcd.
770770
hasContinuation := len(pred.Continue) > 0
771+
// Serve paginated requests about revision "0" from watch cache to avoid overwhelming etcd.
772+
hasLimit := pred.Limit > 0 && resourceVersion != "0"
771773
// Watch cache only supports ResourceVersionMatchNotOlderThan (default).
772-
// see https://kubernetes.io/docs/reference/using-api/api-concepts/#semantics-for-get-and-list
773-
isLegacyExactMatch := opts.Predicate.Limit > 0 && match == "" && len(resourceVersion) > 0 && resourceVersion != "0"
774-
unsupportedMatch := match != "" && match != metav1.ResourceVersionMatchNotOlderThan || isLegacyExactMatch
774+
unsupportedMatch := match != "" && match != metav1.ResourceVersionMatchNotOlderThan
775775

776-
return consistentReadFromStorage || hasContinuation || unsupportedMatch
777-
}
778-
779-
// computeListLimit determines whether the cacher should
780-
// apply a limit to an incoming LIST request and returns its value.
781-
//
782-
// note that this function doesn't check RVM nor the Continuation token.
783-
// these parameters are validated by the shouldDelegateList function.
784-
//
785-
// as of today, the limit is ignored for requests that set RV == 0
786-
func computeListLimit(opts storage.ListOptions) int64 {
787-
if opts.Predicate.Limit <= 0 || opts.ResourceVersion == "0" {
788-
return 0
789-
}
790-
return opts.Predicate.Limit
776+
return consistentReadFromStorage || hasContinuation || hasLimit || unsupportedMatch
791777
}
792778

793779
func shouldDelegateListOnNotReadyCache(opts storage.ListOptions) bool {
@@ -897,21 +883,13 @@ func (c *Cacher) GetList(ctx context.Context, key string, opts storage.ListOptio
897883
// the elements in ListObject are Struct type, making slice will bring excessive memory consumption.
898884
// so we try to delay this action as much as possible
899885
var selectedObjects []runtime.Object
900-
var lastSelectedObjectKey string
901-
var hasMoreListItems bool
902-
limit := computeListLimit(opts)
903-
for i, obj := range objs {
886+
for _, obj := range objs {
904887
elem, ok := obj.(*storeElement)
905888
if !ok {
906889
return fmt.Errorf("non *storeElement returned from storage: %v", obj)
907890
}
908891
if filter(elem.Key, elem.Labels, elem.Fields) {
909892
selectedObjects = append(selectedObjects, elem.Object)
910-
lastSelectedObjectKey = elem.Key
911-
}
912-
if limit > 0 && int64(len(selectedObjects)) >= limit {
913-
hasMoreListItems = i < len(objs)-1
914-
break
915893
}
916894
}
917895
if len(selectedObjects) == 0 {
@@ -927,12 +905,7 @@ func (c *Cacher) GetList(ctx context.Context, key string, opts storage.ListOptio
927905
}
928906
span.AddEvent("Filtered items", attribute.Int("count", listVal.Len()))
929907
if c.versioner != nil {
930-
continueValue, remainingItemCount, err := storage.PrepareContinueToken(lastSelectedObjectKey, key, int64(readResourceVersion), int64(len(objs)), hasMoreListItems, opts)
931-
if err != nil {
932-
return err
933-
}
934-
935-
if err = c.versioner.UpdateList(listObj, readResourceVersion, continueValue, remainingItemCount); err != nil {
908+
if err := c.versioner.UpdateList(listObj, readResourceVersion, "", nil); err != nil {
936909
return err
937910
}
938911
}

staging/src/k8s.io/apiserver/pkg/storage/cacher/cacher_whitebox_test.go

Lines changed: 1 addition & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ func TestGetListCacheBypass(t *testing.T) {
201201
{opts: storage.ListOptions{ResourceVersion: "0", Predicate: storage.SelectionPredicate{Continue: "a"}}, expectBypass: true},
202202
{opts: storage.ListOptions{ResourceVersion: "1", Predicate: storage.SelectionPredicate{Continue: "a"}}, expectBypass: true},
203203

204+
{opts: storage.ListOptions{ResourceVersion: "", Predicate: storage.SelectionPredicate{Limit: 500}}, expectBypass: true},
204205
{opts: storage.ListOptions{ResourceVersion: "0", Predicate: storage.SelectionPredicate{Limit: 500}}, expectBypass: false},
205206
{opts: storage.ListOptions{ResourceVersion: "1", Predicate: storage.SelectionPredicate{Limit: 500}}, expectBypass: true},
206207

@@ -213,7 +214,6 @@ func TestGetListCacheBypass(t *testing.T) {
213214
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ConsistentListFromCache, false)
214215
testCases := append(commonTestCases,
215216
testCase{opts: storage.ListOptions{ResourceVersion: ""}, expectBypass: true},
216-
testCase{opts: storage.ListOptions{ResourceVersion: "", Predicate: storage.SelectionPredicate{Limit: 500}}, expectBypass: true},
217217
)
218218
for _, tc := range testCases {
219219
testGetListCacheBypass(t, tc.opts, tc.expectBypass)
@@ -233,7 +233,6 @@ func TestGetListCacheBypass(t *testing.T) {
233233

234234
testCases := append(commonTestCases,
235235
testCase{opts: storage.ListOptions{ResourceVersion: ""}, expectBypass: false},
236-
testCase{opts: storage.ListOptions{ResourceVersion: "", Predicate: storage.SelectionPredicate{Limit: 500}}, expectBypass: false},
237236
)
238237
for _, tc := range testCases {
239238
testGetListCacheBypass(t, tc.opts, tc.expectBypass)
@@ -2567,63 +2566,6 @@ func TestWatchStreamSeparation(t *testing.T) {
25672566
}
25682567
}
25692568

2570-
func TestComputeListLimit(t *testing.T) {
2571-
scenarios := []struct {
2572-
name string
2573-
opts storage.ListOptions
2574-
expectedLimit int64
2575-
}{
2576-
{
2577-
name: "limit is zero",
2578-
opts: storage.ListOptions{
2579-
Predicate: storage.SelectionPredicate{
2580-
Limit: 0,
2581-
},
2582-
},
2583-
expectedLimit: 0,
2584-
},
2585-
{
2586-
name: "limit is positive, RV is unset",
2587-
opts: storage.ListOptions{
2588-
Predicate: storage.SelectionPredicate{
2589-
Limit: 1,
2590-
},
2591-
ResourceVersion: "",
2592-
},
2593-
expectedLimit: 1,
2594-
},
2595-
{
2596-
name: "limit is positive, RV = 100",
2597-
opts: storage.ListOptions{
2598-
Predicate: storage.SelectionPredicate{
2599-
Limit: 1,
2600-
},
2601-
ResourceVersion: "100",
2602-
},
2603-
expectedLimit: 1,
2604-
},
2605-
{
2606-
name: "legacy case: limit is positive, RV = 0",
2607-
opts: storage.ListOptions{
2608-
Predicate: storage.SelectionPredicate{
2609-
Limit: 1,
2610-
},
2611-
ResourceVersion: "0",
2612-
},
2613-
expectedLimit: 0,
2614-
},
2615-
}
2616-
2617-
for _, scenario := range scenarios {
2618-
t.Run(scenario.name, func(t *testing.T) {
2619-
actualLimit := computeListLimit(scenario.opts)
2620-
if actualLimit != scenario.expectedLimit {
2621-
t.Errorf("computeListLimit returned = %v, expected %v", actualLimit, scenario.expectedLimit)
2622-
}
2623-
})
2624-
}
2625-
}
2626-
26272569
func watchAndWaitForBookmark(t *testing.T, ctx context.Context, etcdStorage storage.Interface) func() (resourceVersion uint64) {
26282570
opts := storage.ListOptions{ResourceVersion: "", Predicate: storage.Everything, Recursive: true}
26292571
opts.Predicate.AllowWatchBookmarks = true

staging/src/k8s.io/apiserver/pkg/util/flowcontrol/request/list_work_estimator.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -173,10 +173,10 @@ func shouldListFromStorage(query url.Values, opts *metav1.ListOptions) bool {
173173
consistentReadFromStorage := resourceVersion == "" && !(consistentListFromCacheEnabled && requestWatchProgressSupported)
174174
// Watch cache doesn't support continuations, so serve them from etcd.
175175
hasContinuation := len(opts.Continue) > 0
176+
// Serve paginated requests about revision "0" from watch cache to avoid overwhelming etcd.
177+
hasLimit := opts.Limit > 0 && resourceVersion != "0"
176178
// Watch cache only supports ResourceVersionMatchNotOlderThan (default).
177-
// see https://kubernetes.io/docs/reference/using-api/api-concepts/#semantics-for-get-and-list
178-
isLegacyExactMatch := opts.Limit > 0 && match == "" && len(resourceVersion) > 0 && resourceVersion != "0"
179-
unsupportedMatch := match != "" && match != metav1.ResourceVersionMatchNotOlderThan || isLegacyExactMatch
179+
unsupportedMatch := match != "" && match != metav1.ResourceVersionMatchNotOlderThan
180180

181-
return consistentReadFromStorage || hasContinuation || unsupportedMatch
181+
return consistentReadFromStorage || hasContinuation || hasLimit || unsupportedMatch
182182
}

0 commit comments

Comments
 (0)