object_cache.go 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /*
  2. Copyright 2016 The Kubernetes Authors.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package cache
  14. import (
  15. "time"
  16. expirationcache "k8s.io/client-go/tools/cache"
  17. )
  18. // ObjectCache is a simple wrapper of expiration cache that
  19. // 1. use string type key
  20. // 2. has an updater to get value directly if it is expired
  21. // 3. then update the cache
  22. type ObjectCache struct {
  23. cache expirationcache.Store
  24. updater func() (interface{}, error)
  25. }
  26. // objectEntry is an object with string type key.
  27. type objectEntry struct {
  28. key string
  29. obj interface{}
  30. }
  31. // NewObjectCache creates ObjectCache with an updater.
  32. // updater returns an object to cache.
  33. func NewObjectCache(f func() (interface{}, error), ttl time.Duration) *ObjectCache {
  34. return &ObjectCache{
  35. updater: f,
  36. cache: expirationcache.NewTTLStore(stringKeyFunc, ttl),
  37. }
  38. }
  39. // stringKeyFunc is a string as cache key function
  40. func stringKeyFunc(obj interface{}) (string, error) {
  41. key := obj.(objectEntry).key
  42. return key, nil
  43. }
  44. // Get gets cached objectEntry by using a unique string as the key.
  45. func (c *ObjectCache) Get(key string) (interface{}, error) {
  46. value, ok, err := c.cache.Get(objectEntry{key: key})
  47. if err != nil {
  48. return nil, err
  49. }
  50. if !ok {
  51. obj, err := c.updater()
  52. if err != nil {
  53. return nil, err
  54. }
  55. err = c.cache.Add(objectEntry{
  56. key: key,
  57. obj: obj,
  58. })
  59. if err != nil {
  60. return nil, err
  61. }
  62. return obj, nil
  63. }
  64. return value.(objectEntry).obj, nil
  65. }
  66. // Add adds objectEntry by using a unique string as the key.
  67. func (c *ObjectCache) Add(key string, obj interface{}) error {
  68. err := c.cache.Add(objectEntry{key: key, obj: obj})
  69. if err != nil {
  70. return err
  71. }
  72. return nil
  73. }