mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-31 07:20:13 +00:00
Merge pull request #38086 from tianshapjq/reduce-decode-times
Automatic merge from submit-queue Reduce decode times by changing the kubectl.Filter(runtime.Object, *PrintOptions)'s return values **What this PR does / why we need it**: In kubectl/cmd/get.go, we use the function filterFuncs.Filter() to decode data and filter the object. But in the following function printer.PrintObj() decodes the data again. I made these modifications to reduce the decoding times by changing the filterFuncs.Filter()'s returned values. We can get the decoded object from this function and pass it to the following printer.PrintObj(), so not to waste time to decode again.
This commit is contained in:
commit
874fca652d
@ -458,8 +458,11 @@ func RunGet(f cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Command, args [
|
||||
lastMapping = mapping
|
||||
}
|
||||
|
||||
// try to convert before apply filter func
|
||||
decodedObj, _ := kubectl.DecodeUnknownObject(original)
|
||||
|
||||
// filter objects if filter has been defined for current object
|
||||
if isFiltered, err := filterFuncs.Filter(original, filterOpts); isFiltered {
|
||||
if isFiltered, err := filterFuncs.Filter(decodedObj, filterOpts); isFiltered {
|
||||
if err == nil {
|
||||
filteredResourceCount++
|
||||
continue
|
||||
@ -489,7 +492,7 @@ func RunGet(f cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Command, args [
|
||||
resourcePrinter.EnsurePrintWithKind(resourceName)
|
||||
}
|
||||
|
||||
if err := printer.PrintObj(original, w); err != nil {
|
||||
if err := printer.PrintObj(decodedObj, w); err != nil {
|
||||
if !errs.Has(err.Error()) {
|
||||
errs.Insert(err.Error())
|
||||
allErrs = append(allErrs, err)
|
||||
@ -497,7 +500,7 @@ func RunGet(f cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Command, args [
|
||||
}
|
||||
continue
|
||||
}
|
||||
if err := printer.PrintObj(original, w); err != nil {
|
||||
if err := printer.PrintObj(decodedObj, w); err != nil {
|
||||
if !errs.Has(err.Error()) {
|
||||
errs.Insert(err.Error())
|
||||
allErrs = append(allErrs, err)
|
||||
|
@ -257,13 +257,23 @@ func TestGetSortedObjects(t *testing.T) {
|
||||
}
|
||||
|
||||
func verifyObjects(t *testing.T, expected, actual []runtime.Object) {
|
||||
var actualObj runtime.Object
|
||||
var err error
|
||||
|
||||
if len(actual) != len(expected) {
|
||||
t.Fatal(actual)
|
||||
}
|
||||
for i, obj := range actual {
|
||||
actualObj, err := runtime.Decode(
|
||||
api.Codecs.UniversalDecoder(),
|
||||
[]byte(runtime.EncodeOrDie(api.Codecs.LegacyCodec(), obj)))
|
||||
switch obj.(type) {
|
||||
case runtime.Unstructured, *runtime.Unknown:
|
||||
actualObj, err = runtime.Decode(
|
||||
api.Codecs.UniversalDecoder(),
|
||||
[]byte(runtime.EncodeOrDie(api.Codecs.LegacyCodec(), obj)))
|
||||
default:
|
||||
actualObj = obj
|
||||
err = nil
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -60,6 +60,20 @@ func filterPods(obj runtime.Object, options PrintOptions) bool {
|
||||
func (f Filters) Filter(obj runtime.Object, opts *PrintOptions) (bool, error) {
|
||||
// check if the object is unstructured. If so, let's attempt to convert it to a type we can understand
|
||||
// before apply filter func.
|
||||
obj, _ = DecodeUnknownObject(obj)
|
||||
|
||||
for _, filter := range f {
|
||||
if ok := filter(obj, *opts); ok {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// check if the object is unstructured. If so, let's attempt to convert it to a type we can understand.
|
||||
func DecodeUnknownObject(obj runtime.Object) (runtime.Object, error) {
|
||||
var err error
|
||||
|
||||
switch obj.(type) {
|
||||
case runtime.Unstructured, *runtime.Unknown:
|
||||
if objBytes, err := runtime.Encode(api.Codecs.LegacyCodec(), obj); err == nil {
|
||||
@ -69,10 +83,5 @@ func (f Filters) Filter(obj runtime.Object, opts *PrintOptions) (bool, error) {
|
||||
}
|
||||
}
|
||||
|
||||
for _, filter := range f {
|
||||
if ok := filter(obj, *opts); ok {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
return obj, err
|
||||
}
|
||||
|
@ -2394,14 +2394,7 @@ func (h *HumanReadablePrinter) PrintObj(obj runtime.Object, output io.Writer) er
|
||||
|
||||
// check if the object is unstructured. If so, let's attempt to convert it to a type we can understand before
|
||||
// trying to print, since the printers are keyed by type. This is extremely expensive.
|
||||
switch obj.(type) {
|
||||
case runtime.Unstructured, *runtime.Unknown:
|
||||
if objBytes, err := runtime.Encode(api.Codecs.LegacyCodec(), obj); err == nil {
|
||||
if decodedObj, err := runtime.Decode(api.Codecs.UniversalDecoder(), objBytes); err == nil {
|
||||
obj = decodedObj
|
||||
}
|
||||
}
|
||||
}
|
||||
obj, _ = DecodeUnknownObject(obj)
|
||||
|
||||
t := reflect.TypeOf(obj)
|
||||
if handler := h.handlerMap[t]; handler != nil {
|
||||
|
Loading…
Reference in New Issue
Block a user