Skip to content

Commit 29fefa0

Browse files
committed
Make background loop run only when LFU or ttl is used
1 parent c9e136c commit 29fefa0

File tree

1 file changed

+27
-15
lines changed

1 file changed

+27
-15
lines changed

cache.go

+27-15
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ type Cache struct {
3939
pool sync.Pool
4040
wg sync.WaitGroup
4141
mu sync.RWMutex
42+
onceLoop sync.Once
4243
lfuEnabled bool
4344
list *ringList
4445
afterEvict EvictionCallback
@@ -93,13 +94,15 @@ func (build Builder) Build() *Cache {
9394
return newRecord()
9495
},
9596
},
96-
stopLoop: make(chan struct{}),
97+
stopLoop: make(chan struct{}, 1),
9798
}
9899
build(c)
99100
if c.list == nil {
100101
c.list = newRingList(0)
101102
}
102-
go c.runLoop()
103+
if c.lfuEnabled {
104+
c.runLoop()
105+
}
103106
return c
104107
}
105108

@@ -138,6 +141,9 @@ func (c *Cache) Set(key, value interface{}, ttl time.Duration) {
138141
old, loaded := c.records.LoadOrStore(key, r)
139142
if !loaded {
140143
r.init(value, ttl)
144+
if ttl > 0 {
145+
c.runLoop()
146+
}
141147
if front := c.list.PushBack(key, r.ring); front != nil {
142148
c.Evict(front)
143149
}
@@ -174,6 +180,9 @@ func (c *Cache) Fetch(key interface{}, ttl time.Duration, f FetchCallback) (valu
174180
return nil, false
175181
}
176182
r.init(value, ttl)
183+
if ttl > 0 {
184+
c.runLoop()
185+
}
177186
r.wg.Add(1)
178187
if front := c.list.PushBack(key, r.ring); front != nil {
179188
c.Evict(front)
@@ -227,11 +236,9 @@ func (c *Cache) Range(f func(key, value interface{}) bool) {
227236
// It is not safe to use OrderedRange concurrently with any other method
228237
// except Exists and Get or a deadlock may occur.
229238
func (c *Cache) OrderedRange(f func(key, value interface{}) bool) {
239+
c.runLoop()
230240
c.stopLoop <- struct{}{}
231241
c.wg.Wait()
232-
defer func() {
233-
go c.runLoop()
234-
}()
235242
c.list.Do(func(key interface{}) bool {
236243
r, ok := c.records.Load(key)
237244
if !ok {
@@ -300,6 +307,7 @@ func (c *Cache) Len() int {
300307
// It is not safe to close the cache
301308
// while in use.
302309
func (c *Cache) Close() error {
310+
c.runLoop()
303311
c.stopLoop <- struct{}{}
304312
close(c.stopLoop)
305313
c.Flush()
@@ -374,16 +382,20 @@ func (c *Cache) finalizeAsync(key interface{}, r *record) {
374382
}
375383

376384
func (c *Cache) runLoop() {
377-
ticker := time.NewTicker(SyncInterval)
378-
defer ticker.Stop()
379-
for {
380-
select {
381-
case <-c.stopLoop:
382-
return
383-
case now := <-ticker.C:
384-
c.processRecords(now.UnixNano())
385-
}
386-
}
385+
c.onceLoop.Do(func() {
386+
go func() {
387+
ticker := time.NewTicker(SyncInterval)
388+
defer ticker.Stop()
389+
for {
390+
select {
391+
case <-c.stopLoop:
392+
return
393+
case now := <-ticker.C:
394+
c.processRecords(now.UnixNano())
395+
}
396+
}
397+
}()
398+
})
387399
}
388400

389401
func (c *Cache) processRecords(now int64) {

0 commit comments

Comments
 (0)