Properly account APF seats for legacy watches that compute init-events

This commit is contained in:
Shyam Jeedigunta
2025-10-14 13:23:28 -07:00
parent 9630ab9581
commit 678b79a173
2 changed files with 83 additions and 8 deletions

View File

@@ -86,10 +86,12 @@ func (e *listWorkEstimator) estimate(r *http.Request, flowSchemaName, priorityLe
return WorkEstimate{InitialSeats: maxSeats}
}
// For watch requests, we want to adjust the cost only if they explicitly request
// sending initial events.
// For watch requests we want to set the cost low if they aren't requesting for init events,
// either via the explicit SendInitialEvents param or via legacy watches that have RV=0 or unset.
if requestInfo.Verb == "watch" {
if listOptions.SendInitialEvents == nil || !*listOptions.SendInitialEvents {
sendInitEvents := listOptions.SendInitialEvents != nil && *listOptions.SendInitialEvents
legacyWatch := listOptions.ResourceVersion == "" || listOptions.ResourceVersion == "0"
if !sendInitEvents && !legacyWatch {
return WorkEstimate{InitialSeats: e.config.MinimumSeats}
}
}

View File

@@ -598,30 +598,79 @@ func TestWorkEstimator(t *testing.T) {
initialSeatsExpected: 3,
},
{
name: "request verb is watch, sendInitialEvents is nil",
name: "request verb is watch, sendInitialEvents is nil and RV unset (legacy watch with init events)",
requestURI: "http://server/apis/foo.bar/v1/events?watch=true",
requestInfo: &apirequest.RequestInfo{
Verb: "watch",
APIGroup: "foo.bar",
Resource: "events",
},
stats: storage.Stats{ObjectCount: 799, EstimatedAverageObjectSizeBytes: 10_000},
stats: storage.Stats{ObjectCount: 799, EstimatedAverageObjectSizeBytes: 1_000},
maxSeats: 100,
initialSeatsExpected: 8,
},
{
name: "request verb is watch, sendInitialEvents is nil and RV set to 0 (legacy watch with init events)",
requestURI: "http://server/apis/foo.bar/v1/events?watch=true&resourceVersion=0",
requestInfo: &apirequest.RequestInfo{
Verb: "watch",
APIGroup: "foo.bar",
Resource: "events",
},
stats: storage.Stats{ObjectCount: 799, EstimatedAverageObjectSizeBytes: 1_000},
maxSeats: 100,
initialSeatsExpected: 8,
},
{
name: "request verb is watch, sendInitialEvents is nil and RV set to non-zero (legacy watch without init events)",
requestURI: "http://server/apis/foo.bar/v1/events?watch=true&resourceVersion=1",
requestInfo: &apirequest.RequestInfo{
Verb: "watch",
APIGroup: "foo.bar",
Resource: "events",
},
stats: storage.Stats{ObjectCount: 799, EstimatedAverageObjectSizeBytes: 1_000},
maxSeats: 100,
initialSeatsExpected: 1,
},
{
name: "request verb is watch, sendInitialEvents is false",
name: "request verb is watch, sendInitialEvents is false and RV unset (legacy watch with init events)",
requestURI: "http://server/apis/foo.bar/v1/events?watch=true&sendInitialEvents=false",
requestInfo: &apirequest.RequestInfo{
Verb: "watch",
APIGroup: "foo.bar",
Resource: "events",
},
stats: storage.Stats{ObjectCount: 799, EstimatedAverageObjectSizeBytes: 10_000},
stats: storage.Stats{ObjectCount: 799, EstimatedAverageObjectSizeBytes: 1_000},
maxSeats: 100,
initialSeatsExpected: 8,
},
{
name: "request verb is watch, sendInitialEvents is false and RV set to 0 (legacy watch with init events)",
requestURI: "http://server/apis/foo.bar/v1/events?watch=true&sendInitialEvents=false&resourceVersion=0",
requestInfo: &apirequest.RequestInfo{
Verb: "watch",
APIGroup: "foo.bar",
Resource: "events",
},
stats: storage.Stats{ObjectCount: 799, EstimatedAverageObjectSizeBytes: 1_000},
maxSeats: 100,
initialSeatsExpected: 8,
},
{
name: "request verb is watch, sendInitialEvents is false and RV set to non-zero (legacy watch without init events))",
requestURI: "http://server/apis/foo.bar/v1/events?watch=true&sendInitialEvents=false&resourceVersion=1",
requestInfo: &apirequest.RequestInfo{
Verb: "watch",
APIGroup: "foo.bar",
Resource: "events",
},
stats: storage.Stats{ObjectCount: 799, EstimatedAverageObjectSizeBytes: 1_000},
maxSeats: 100,
initialSeatsExpected: 1,
},
{
name: "request verb is watch, sendInitialEvents is true",
name: "request verb is watch, sendInitialEvents is true and RV unset (streaming list with init events)",
requestURI: "http://server/apis/foo.bar/v1/events?watch=true&sendInitialEvents=true",
requestInfo: &apirequest.RequestInfo{
Verb: "watch",
@@ -632,6 +681,30 @@ func TestWorkEstimator(t *testing.T) {
maxSeats: 100,
initialSeatsExpected: 8,
},
{
name: "request verb is watch, sendInitialEvents is true and RV set to 0 (streaming list with init events)",
requestURI: "http://server/apis/foo.bar/v1/events?watch=true&sendInitialEvents=true&resourceVersion=0",
requestInfo: &apirequest.RequestInfo{
Verb: "watch",
APIGroup: "foo.bar",
Resource: "events",
},
stats: storage.Stats{ObjectCount: 799, EstimatedAverageObjectSizeBytes: 1_000},
maxSeats: 100,
initialSeatsExpected: 8,
},
{
name: "request verb is watch, sendInitialEvents is true and RV set to non-zero (streaming list with init events)",
requestURI: "http://server/apis/foo.bar/v1/events?watch=true&sendInitialEvents=true&resourceVersion=0",
requestInfo: &apirequest.RequestInfo{
Verb: "watch",
APIGroup: "foo.bar",
Resource: "events",
},
stats: storage.Stats{ObjectCount: 799, EstimatedAverageObjectSizeBytes: 1_000},
maxSeats: 100,
initialSeatsExpected: 8,
},
{
name: "request verb is create, no watches",
requestURI: "http://server/apis/foo.bar/v1/foos",