janitor.go

v0.2.0
Doc Versions Source
1
package cache
2
3
import (
4
	"context"
5
	"time"
6
)
7
8
type janitor[K comparable, V any] struct {
9
	interval time.Duration
10
	cache    *cache[K, V]
11
	cancel   context.CancelFunc
12
	done     chan struct{}
13
}
14
15
func newJanitor[K comparable, V any](c *cache[K, V], interval time.Duration) *janitor[K, V] {
16
	return &janitor[K, V]{
17
		interval: interval,
18
		cache:    c,
19
	}
20
}
21
22
// Start begins the background sweep goroutine. It panics if the janitor is
23
// already running. If the interval is not positive, Start is a no-op.
24
func (j *janitor[K, V]) Start(ctx context.Context) {
25
	if j.cancel != nil {
26
		panic("cache: janitor already started")
27
	}
28
	if j.interval <= 0 {
29
		return
30
	}
31
	ctx, j.cancel = context.WithCancel(ctx)
32
	j.done = make(chan struct{})
33
	go j.loop(ctx)
34
}
35
36
// Stop stops the background sweep goroutine and waits for it to exit.
37
func (j *janitor[K, V]) Stop() {
38
	if j.cancel == nil {
39
		return
40
	}
41
	j.cancel()
42
	<-j.done
43
	j.cancel = nil
44
}
45
46
func (j *janitor[K, V]) loop(ctx context.Context) {
47
	defer close(j.done)
48
	ticker := time.NewTicker(j.interval)
49
	defer ticker.Stop()
50
	for {
51
		select {
52
		case <-ticker.C:
53
			j.cache.DeleteExpired()
54
		case <-ctx.Done():
55
			return
56
		}
57
	}
58
}
59

Source Files