runtime_cache.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. /*
  2. Copyright 2015 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 container
  14. import (
  15. "sync"
  16. "time"
  17. )
  18. var (
  19. // TODO(yifan): Maybe set the them as parameters for NewCache().
  20. defaultCachePeriod = time.Second * 2
  21. )
  22. type RuntimeCache interface {
  23. GetPods() ([]*Pod, error)
  24. ForceUpdateIfOlder(time.Time) error
  25. }
  26. type podsGetter interface {
  27. GetPods(bool) ([]*Pod, error)
  28. }
  29. // NewRuntimeCache creates a container runtime cache.
  30. func NewRuntimeCache(getter podsGetter) (RuntimeCache, error) {
  31. return &runtimeCache{
  32. getter: getter,
  33. }, nil
  34. }
  35. // runtimeCache caches a list of pods. It records a timestamp (cacheTime) right
  36. // before updating the pods, so the timestamp is at most as new as the pods
  37. // (and can be slightly older). The timestamp always moves forward. Callers are
  38. // expected not to modify the pods returned from GetPods.
  39. type runtimeCache struct {
  40. sync.Mutex
  41. // The underlying container runtime used to update the cache.
  42. getter podsGetter
  43. // Last time when cache was updated.
  44. cacheTime time.Time
  45. // The content of the cache.
  46. pods []*Pod
  47. }
  48. // GetPods returns the cached pods if they are not outdated; otherwise, it
  49. // retrieves the latest pods and return them.
  50. func (r *runtimeCache) GetPods() ([]*Pod, error) {
  51. r.Lock()
  52. defer r.Unlock()
  53. if time.Since(r.cacheTime) > defaultCachePeriod {
  54. if err := r.updateCache(); err != nil {
  55. return nil, err
  56. }
  57. }
  58. return r.pods, nil
  59. }
  60. func (r *runtimeCache) ForceUpdateIfOlder(minExpectedCacheTime time.Time) error {
  61. r.Lock()
  62. defer r.Unlock()
  63. if r.cacheTime.Before(minExpectedCacheTime) {
  64. return r.updateCache()
  65. }
  66. return nil
  67. }
  68. func (r *runtimeCache) updateCache() error {
  69. pods, timestamp, err := r.getPodsWithTimestamp()
  70. if err != nil {
  71. return err
  72. }
  73. r.pods, r.cacheTime = pods, timestamp
  74. return nil
  75. }
  76. // getPodsWithTimestamp records a timestamp and retrieves pods from the getter.
  77. func (r *runtimeCache) getPodsWithTimestamp() ([]*Pod, time.Time, error) {
  78. // Always record the timestamp before getting the pods to avoid stale pods.
  79. timestamp := time.Now()
  80. pods, err := r.getter.GetPods(false)
  81. return pods, timestamp, err
  82. }