From f670cc465211fb5328ee2beae330a6625750471c Mon Sep 17 00:00:00 2001 From: Clayton Coleman Date: Sat, 21 May 2016 00:05:39 -0400 Subject: [PATCH] Avoid multiple allocations during selfLink generation --- pkg/apiserver/api_installer.go | 21 ++++++++++++++------- pkg/apiserver/api_installer_test.go | 4 +++- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/pkg/apiserver/api_installer.go b/pkg/apiserver/api_installer.go index 423f09bfc4e..4a27a2ee126 100644 --- a/pkg/apiserver/api_installer.go +++ b/pkg/apiserver/api_installer.go @@ -390,18 +390,26 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag resourcePath := namespacedPath resourceParams := namespaceParams + itemPathPrefix := gpath.Join(a.prefix, scope.ParamName()) + "/" itemPath := namespacedPath + "/{name}" + itemPathMiddle := "/" + resource + "/" nameParams := append(namespaceParams, nameParam) proxyParams := append(nameParams, pathParam) + itemPathSuffix := "" if hasSubresource { - itemPath = itemPath + "/" + subresource + itemPathSuffix = "/" + subresource + itemPath = itemPath + itemPathSuffix resourcePath = itemPath resourceParams = nameParams } apiResource.Name = path apiResource.Namespaced = true apiResource.Kind = resourceKind - namer := scopeNaming{scope, a.group.Linker, gpath.Join(a.prefix, itemPath), false} + + itemPathFn := func(name, namespace string) string { + return itemPathPrefix + namespace + itemPathMiddle + name + itemPathSuffix + } + namer := scopeNaming{scope, a.group.Linker, itemPathFn, false} actions = appendIf(actions, action{"LIST", resourcePath, resourceParams, namer}, isLister) actions = appendIf(actions, action{"POST", resourcePath, resourceParams, namer}, isCreater) @@ -430,7 +438,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag // For ex: LIST all pods in all namespaces by sending a LIST request at /api/apiVersion/pods. // TODO: more strongly type whether a resource allows these actions on "all namespaces" (bulk delete) if !hasSubresource { - namer = scopeNaming{scope, a.group.Linker, gpath.Join(a.prefix, itemPath), true} + namer = scopeNaming{scope, a.group.Linker, itemPathFn, true} actions = appendIf(actions, action{"LIST", resource, params, namer}, isLister) actions = appendIf(actions, action{"WATCHLIST", "watch/" + resource, params, namer}, allowWatchList) } @@ -775,7 +783,7 @@ func (n rootScopeNaming) ObjectName(obj runtime.Object) (namespace, name string, type scopeNaming struct { scope meta.RESTScope runtime.SelfLinker - itemPath string + itemPathFn func(name, namespace string) string allNamespaces bool } @@ -822,9 +830,8 @@ func (n scopeNaming) GenerateLink(req *restful.Request, obj runtime.Object) (pat if len(name) == 0 { return "", "", errEmptyName } - path = strings.Replace(n.itemPath, "{name}", name, 1) - path = strings.Replace(path, "{"+n.scope.ArgumentName()+"}", namespace, 1) - return path, "", nil + + return n.itemPathFn(name, namespace), "", nil } // GenerateListLink returns the appropriate path and query to locate a list by its canonical path. diff --git a/pkg/apiserver/api_installer_test.go b/pkg/apiserver/api_installer_test.go index 57df10e94c4..3d5f2b869a4 100644 --- a/pkg/apiserver/api_installer_test.go +++ b/pkg/apiserver/api_installer_test.go @@ -36,7 +36,9 @@ func TestScopeNamingGenerateLink(t *testing.T) { s := scopeNaming{ meta.RESTScopeNamespace, selfLinker, - "/api/v1/namespaces/{namespace}/services/{name}", + func(name, namespace string) string { + return "/api/v1/namespaces/" + namespace + "/services/" + name + }, true, } service := &api.Service{