This commit is contained in:
Kevin Delgado 2021-07-19 20:50:50 +00:00
parent f6ce385e44
commit 7cb18e84f1
5 changed files with 18 additions and 16 deletions

View File

@ -19,14 +19,8 @@ type UnstructuredExtractor interface {
ExtractUnstructuredStatus(object *unstructured.Unstructured, fieldManager string) (*unstructured.Unstructured, error) ExtractUnstructuredStatus(object *unstructured.Unstructured, fieldManager string) (*unstructured.Unstructured, error)
} }
//// objectTypeCache is a cache of typed.ParseableTypes // objectTypeCache caches the GVKParser in order to prevent from having to repeatedly
//type objectTypeCache interface { // parse the models from the open API schema when the schema itself changes infrequently.
// objectTypeForGVK(gvk schema.GroupVersionKind) (*typed.ParseableType, error)
//}
// objectTypeCache is a objectTypeCache that does no caching
// (i.e. it downloads the OpenAPISchema every time)
// Useful during the proof-of-concept stage until we agree on a caching solution.
type objectTypeCache struct { type objectTypeCache struct {
// TODO: lock this? // TODO: lock this?
discoveryClient discovery.DiscoveryInterface discoveryClient discovery.DiscoveryInterface
@ -35,7 +29,6 @@ type objectTypeCache struct {
// objectTypeForGVK retrieves the typed.ParseableType for a given gvk from the cache // objectTypeForGVK retrieves the typed.ParseableType for a given gvk from the cache
func (c *objectTypeCache) objectTypeForGVK(gvk schema.GroupVersionKind) (*typed.ParseableType, error) { func (c *objectTypeCache) objectTypeForGVK(gvk schema.GroupVersionKind) (*typed.ParseableType, error) {
if !c.discoveryClient.HasOpenAPISchemaChanged() && c.gvkParser != nil { if !c.discoveryClient.HasOpenAPISchemaChanged() && c.gvkParser != nil {
// cache hit // cache hit
fmt.Println("cache hit") fmt.Println("cache hit")

View File

@ -240,6 +240,7 @@ func (d *CachedDiscoveryClient) OpenAPISchema() (*openapi_v2.Document, error) {
return d.delegate.OpenAPISchema() return d.delegate.OpenAPISchema()
} }
// HasOpenAPISchemaChanged checks wether the open API schema being served is cached or not.
func (d *CachedDiscoveryClient) HasOpenAPISchemaChanged() bool { func (d *CachedDiscoveryClient) HasOpenAPISchemaChanged() bool {
return d.delegate.HasOpenAPISchemaChanged() return d.delegate.HasOpenAPISchemaChanged()
} }

View File

@ -122,11 +122,14 @@ type ServerVersionInterface interface {
ServerVersion() (*version.Info, error) ServerVersion() (*version.Info, error)
} }
// OpenAPISchemaInterface has a method to retrieve the open API schema. // OpenAPISchemaInterface has a method to retrieve the open API schema
// and a method to check whether the open API schema has changed.
type OpenAPISchemaInterface interface { type OpenAPISchemaInterface interface {
// OpenAPISchema retrieves and parses the swagger API schema the server supports. // OpenAPISchema retrieves and parses the swagger API schema the server supports.
OpenAPISchema() (*openapi_v2.Document, error) OpenAPISchema() (*openapi_v2.Document, error)
// HasOpenAPISchema changed checks whether the API schema being served
// by the apiserver is cached (and thus has not changed).
HasOpenAPISchemaChanged() bool HasOpenAPISchemaChanged() bool
} }
@ -423,6 +426,8 @@ func (d *DiscoveryClient) ServerVersion() (*version.Info, error) {
return &info, nil return &info, nil
} }
// HasOpenAPISchemaChanged checks whether a HEAD request to openapi endpoint returns
// a 304 StatusNotModified meaning it has not changed.
func (d *DiscoveryClient) HasOpenAPISchemaChanged() bool { func (d *DiscoveryClient) HasOpenAPISchemaChanged() bool {
result := d.restClient.Verb("HEAD").AbsPath("/openapi/v2").SetHeader("If-None-Match", d.etag).SetHeader("Accept", mimePb).Do(context.TODO()) result := d.restClient.Verb("HEAD").AbsPath("/openapi/v2").SetHeader("If-None-Match", d.etag).SetHeader("Accept", mimePb).Do(context.TODO())
var status int var status int

View File

@ -153,6 +153,7 @@ func (c *FakeDiscovery) OpenAPISchema() (*openapi_v2.Document, error) {
return &openapi_v2.Document{}, nil return &openapi_v2.Document{}, nil
} }
// HasOpenAPISchemaChanged checks wether the open API schema being served is cached or not.
func (c *FakeDiscovery) HasOpenAPISchemaChanged() bool { func (c *FakeDiscovery) HasOpenAPISchemaChanged() bool {
return true return true
} }

View File

@ -1062,12 +1062,6 @@ func (r *Request) DoRaw(ctx context.Context) ([]byte, error) {
// transformResponse converts an API response into a structured API object // transformResponse converts an API response into a structured API object
func (r *Request) transformResponse(resp *http.Response, req *http.Request) Result { func (r *Request) transformResponse(resp *http.Response, req *http.Request) Result {
var etag string
etagHeader, ok := resp.Header["Etag"]
if ok && len(etagHeader) == 1 {
etag = etagHeader[0]
}
var body []byte var body []byte
if resp.Body != nil { if resp.Body != nil {
data, err := ioutil.ReadAll(resp.Body) data, err := ioutil.ReadAll(resp.Body)
@ -1146,6 +1140,14 @@ func (r *Request) transformResponse(resp *http.Response, req *http.Request) Resu
} }
} }
// store the etag header so that we can check whether the document
// has changed or not.
var etag string
etagHeader, ok := resp.Header["Etag"]
if ok && len(etagHeader) == 1 {
etag = etagHeader[0]
}
return Result{ return Result{
body: body, body: body,
contentType: contentType, contentType: contentType,