Fix cacheWatcher leak when time jump to the future and jump back

This commit is contained in:
chenyw1990 2020-11-05 22:02:41 +08:00
parent 912f5ec5c4
commit 36d5db95f8

View File

@ -158,8 +158,10 @@ func (i *indexedWatchers) terminateAll(objectType reflect.Type, done func(*cache
// second in a bucket, and pop up them once at the timeout. To be more specific, // second in a bucket, and pop up them once at the timeout. To be more specific,
// if you set fire time at X, you can get the bookmark within (X-1,X+1) period. // if you set fire time at X, you can get the bookmark within (X-1,X+1) period.
type watcherBookmarkTimeBuckets struct { type watcherBookmarkTimeBuckets struct {
lock sync.Mutex lock sync.Mutex
// the key of watcherBuckets is the number of seconds since createTime
watchersBuckets map[int64][]*cacheWatcher watchersBuckets map[int64][]*cacheWatcher
createTime time.Time
startBucketID int64 startBucketID int64
clock clock.Clock clock clock.Clock
bookmarkFrequency time.Duration bookmarkFrequency time.Duration
@ -168,7 +170,8 @@ type watcherBookmarkTimeBuckets struct {
func newTimeBucketWatchers(clock clock.Clock, bookmarkFrequency time.Duration) *watcherBookmarkTimeBuckets { func newTimeBucketWatchers(clock clock.Clock, bookmarkFrequency time.Duration) *watcherBookmarkTimeBuckets {
return &watcherBookmarkTimeBuckets{ return &watcherBookmarkTimeBuckets{
watchersBuckets: make(map[int64][]*cacheWatcher), watchersBuckets: make(map[int64][]*cacheWatcher),
startBucketID: clock.Now().Unix(), createTime: clock.Now(),
startBucketID: 0,
clock: clock, clock: clock,
bookmarkFrequency: bookmarkFrequency, bookmarkFrequency: bookmarkFrequency,
} }
@ -181,7 +184,7 @@ func (t *watcherBookmarkTimeBuckets) addWatcher(w *cacheWatcher) bool {
if !ok { if !ok {
return false return false
} }
bucketID := nextTime.Unix() bucketID := int64(nextTime.Sub(t.createTime) / time.Second)
t.lock.Lock() t.lock.Lock()
defer t.lock.Unlock() defer t.lock.Unlock()
if bucketID < t.startBucketID { if bucketID < t.startBucketID {
@ -193,7 +196,7 @@ func (t *watcherBookmarkTimeBuckets) addWatcher(w *cacheWatcher) bool {
} }
func (t *watcherBookmarkTimeBuckets) popExpiredWatchers() [][]*cacheWatcher { func (t *watcherBookmarkTimeBuckets) popExpiredWatchers() [][]*cacheWatcher {
currentBucketID := t.clock.Now().Unix() currentBucketID := int64(t.clock.Since(t.createTime) / time.Second)
// There should be one or two elements in almost all cases // There should be one or two elements in almost all cases
expiredWatchers := make([][]*cacheWatcher, 0, 2) expiredWatchers := make([][]*cacheWatcher, 0, 2)
t.lock.Lock() t.lock.Lock()