From 6cab3a7bec75e42581e8041395c3ceaa14e07c74 Mon Sep 17 00:00:00 2001 From: jennybuckley Date: Thu, 9 Jan 2020 14:15:34 -0800 Subject: [PATCH 1/2] create probabilistic SkipNonAppliedManager --- .../handlers/fieldmanager/fieldmanager.go | 6 ++++- .../handlers/fieldmanager/skipnonapplied.go | 27 ++++++++++++++++++- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/fieldmanager.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/fieldmanager.go index 3f2b08984ea..f76dc2c5322 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/fieldmanager.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/fieldmanager.go @@ -33,6 +33,10 @@ import ( // TODO(jennybuckley): Determine if this is really the best value. Ideally we wouldn't unnecessarily merge too many entries. const DefaultMaxUpdateManagers int = 10 +// DefaultTrackOnCreateProbability defines the default probability that the field management of an object +// starts being tracked from the object's creation, instead of from the first time the object is applied to. +const DefaultTrackOnCreateProbability float32 = 0.11494204485329620070 + // Managed groups a fieldpath.ManagedFields together with the timestamps associated with each operation. type Managed interface { // Fields gets the fieldpath.ManagedFields. @@ -92,7 +96,7 @@ func newDefaultFieldManager(f Manager, objectCreater runtime.ObjectCreater, kind f = NewStripMetaManager(f) f = NewBuildManagerInfoManager(f, kind.GroupVersion()) f = NewCapManagersManager(f, DefaultMaxUpdateManagers) - f = NewSkipNonAppliedManager(f, objectCreater, kind) + f = NewProbabilisticSkipNonAppliedManager(f, objectCreater, kind, DefaultTrackOnCreateProbability) return NewFieldManager(f) } diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/skipnonapplied.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/skipnonapplied.go index 4230a61d644..b115346d0fd 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/skipnonapplied.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/skipnonapplied.go @@ -18,7 +18,9 @@ package fieldmanager import ( "fmt" + "math/rand" + "k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" ) @@ -28,25 +30,48 @@ type skipNonAppliedManager struct { objectCreater runtime.ObjectCreater gvk schema.GroupVersionKind beforeApplyManagerName string + probability float32 } var _ Manager = &skipNonAppliedManager{} // NewSkipNonAppliedManager creates a new wrapped FieldManager that only starts tracking managers after the first apply. func NewSkipNonAppliedManager(fieldManager Manager, objectCreater runtime.ObjectCreater, gvk schema.GroupVersionKind) Manager { + return NewProbabilisticSkipNonAppliedManager(fieldManager, objectCreater, gvk, 0.0) +} + +// NewProbabilisticSkipNonAppliedManager creates a new wrapped FieldManager that starts tracking managers after the first apply, +// or starts tracking on create with p probability. +func NewProbabilisticSkipNonAppliedManager(fieldManager Manager, objectCreater runtime.ObjectCreater, gvk schema.GroupVersionKind, p float32) Manager { return &skipNonAppliedManager{ fieldManager: fieldManager, objectCreater: objectCreater, gvk: gvk, beforeApplyManagerName: "before-first-apply", + probability: p, } } // Update implements Manager. func (f *skipNonAppliedManager) Update(liveObj, newObj runtime.Object, managed Managed, manager string) (runtime.Object, Managed, error) { - if len(managed.Fields()) == 0 { + accessor, err := meta.Accessor(liveObj) + if err != nil { return newObj, managed, nil } + + // If managed fields is empty, we need to determine whether to skip tracking managed fields. + if len(managed.Fields()) == 0 { + // Check if the operation is a create, by checking whether lastObj's UID is empty. + // If the operation is create, P(tracking managed fields) = f.probability + // If the operation is update, skip tracking managed fields, since we already know managed fields is empty. + if len(accessor.GetUID()) == 0 { + if f.probability <= rand.Float32() { + return newObj, managed, nil + } + } else { + return newObj, managed, nil + } + } return f.fieldManager.Update(liveObj, newObj, managed, manager) } From 4db3822ebbac30248463eb529d88176f8b258fd9 Mon Sep 17 00:00:00 2001 From: Jennifer Buckley Date: Fri, 10 Jan 2020 11:15:06 -0800 Subject: [PATCH 2/2] Update fieldmanager.go --- .../pkg/endpoints/handlers/fieldmanager/fieldmanager.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/fieldmanager.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/fieldmanager.go index f76dc2c5322..91cf68845e2 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/fieldmanager.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/fieldmanager.go @@ -35,7 +35,7 @@ const DefaultMaxUpdateManagers int = 10 // DefaultTrackOnCreateProbability defines the default probability that the field management of an object // starts being tracked from the object's creation, instead of from the first time the object is applied to. -const DefaultTrackOnCreateProbability float32 = 0.11494204485329620070 +const DefaultTrackOnCreateProbability float32 = 0.5 // Managed groups a fieldpath.ManagedFields together with the timestamps associated with each operation. type Managed interface {