@@ -39,6 +39,7 @@ type Cache struct {
39
39
pool sync.Pool
40
40
wg sync.WaitGroup
41
41
mu sync.RWMutex
42
+ onceLoop sync.Once
42
43
lfuEnabled bool
43
44
list * ringList
44
45
afterEvict EvictionCallback
@@ -93,13 +94,15 @@ func (build Builder) Build() *Cache {
93
94
return newRecord ()
94
95
},
95
96
},
96
- stopLoop : make (chan struct {}),
97
+ stopLoop : make (chan struct {}, 1 ),
97
98
}
98
99
build (c )
99
100
if c .list == nil {
100
101
c .list = newRingList (0 )
101
102
}
102
- go c .runLoop ()
103
+ if c .lfuEnabled {
104
+ c .runLoop ()
105
+ }
103
106
return c
104
107
}
105
108
@@ -138,6 +141,9 @@ func (c *Cache) Set(key, value interface{}, ttl time.Duration) {
138
141
old , loaded := c .records .LoadOrStore (key , r )
139
142
if ! loaded {
140
143
r .init (value , ttl )
144
+ if ttl > 0 {
145
+ c .runLoop ()
146
+ }
141
147
if front := c .list .PushBack (key , r .ring ); front != nil {
142
148
c .Evict (front )
143
149
}
@@ -174,6 +180,9 @@ func (c *Cache) Fetch(key interface{}, ttl time.Duration, f FetchCallback) (valu
174
180
return nil , false
175
181
}
176
182
r .init (value , ttl )
183
+ if ttl > 0 {
184
+ c .runLoop ()
185
+ }
177
186
r .wg .Add (1 )
178
187
if front := c .list .PushBack (key , r .ring ); front != nil {
179
188
c .Evict (front )
@@ -227,11 +236,9 @@ func (c *Cache) Range(f func(key, value interface{}) bool) {
227
236
// It is not safe to use OrderedRange concurrently with any other method
228
237
// except Exists and Get or a deadlock may occur.
229
238
func (c * Cache ) OrderedRange (f func (key , value interface {}) bool ) {
239
+ c .runLoop ()
230
240
c .stopLoop <- struct {}{}
231
241
c .wg .Wait ()
232
- defer func () {
233
- go c .runLoop ()
234
- }()
235
242
c .list .Do (func (key interface {}) bool {
236
243
r , ok := c .records .Load (key )
237
244
if ! ok {
@@ -300,6 +307,7 @@ func (c *Cache) Len() int {
300
307
// It is not safe to close the cache
301
308
// while in use.
302
309
func (c * Cache ) Close () error {
310
+ c .runLoop ()
303
311
c .stopLoop <- struct {}{}
304
312
close (c .stopLoop )
305
313
c .Flush ()
@@ -374,16 +382,20 @@ func (c *Cache) finalizeAsync(key interface{}, r *record) {
374
382
}
375
383
376
384
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
+ })
387
399
}
388
400
389
401
func (c * Cache ) processRecords (now int64 ) {
0 commit comments