From fa1e39166160351695e6e0bd64e86cbb469c2c04 Mon Sep 17 00:00:00 2001 From: Patrick Ohly Date: Tue, 26 Apr 2022 14:42:44 +0200 Subject: [PATCH] optimize KObjs KObjs used to do significant work regardless whether the log entry would get written at all. We can delay doing that work and (typically) skip it entirely by just capturing the parameter and lazily converting to the actual slice if needed in MarshalLog. This depends on MarshalLog support in klog and other logger backends. If changing the output to a string is acceptable, then adding a String function is a safer alternative. --- k8s_references.go | 25 ++++++++++++++++++++----- klog_test.go | 5 +++-- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/k8s_references.go b/k8s_references.go index db58f8baa..b22778739 100644 --- a/k8s_references.go +++ b/k8s_references.go @@ -76,19 +76,34 @@ func KRef(namespace, name string) ObjectRef { } } -// KObjs returns slice of ObjectRef from an slice of ObjectMeta -func KObjs(arg interface{}) []ObjectRef { - s := reflect.ValueOf(arg) +type kobjs struct { + arg interface{} +} + +func (k kobjs) MarshalLog() interface{} { + s := reflect.ValueOf(k.arg) + var empty []ObjectRef if s.Kind() != reflect.Slice { - return nil + // This mirrors the traditional behavior, but perhaps isn't + // what we want? + return empty } objectRefs := make([]ObjectRef, 0, s.Len()) for i := 0; i < s.Len(); i++ { if v, ok := s.Index(i).Interface().(KMetadata); ok { objectRefs = append(objectRefs, KObj(v)) } else { - return nil + // This mirrors the traditional behavior, but perhaps isn't + // what we want? + return empty } } return objectRefs } + +// KObjs returns an object that will be logged like +// a slice of ObjectRefs for each entry in the parameter +// slice. If the parameter is not a slice, nil will be logged. +func KObjs(arg interface{}) logr.Marshaler { + return kobjs{arg} +} diff --git a/klog_test.go b/klog_test.go index 3a9b4494b..658f1cef4 100644 --- a/klog_test.go +++ b/klog_test.go @@ -1845,8 +1845,9 @@ func TestKObjs(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if !reflect.DeepEqual(KObjs(tt.obj), tt.want) { - t.Errorf("\nwant:\t %v\n got:\t %v", tt.want, KObjs(tt.obj)) + got := KObjs(tt.obj).MarshalLog() + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("\nwant:\t %v\n got:\t %v", tt.want, got) } }) }