github.com/thanos-io/thanos@v0.32.5/internal/cortex/chunk/cache/background.go (about) 1 // Copyright (c) The Cortex Authors. 2 // Licensed under the Apache License 2.0. 3 4 package cache 5 6 import ( 7 "context" 8 "flag" 9 "sync" 10 11 "github.com/prometheus/client_golang/prometheus" 12 "github.com/prometheus/client_golang/prometheus/promauto" 13 ) 14 15 // BackgroundConfig is config for a Background Cache. 16 type BackgroundConfig struct { 17 WriteBackGoroutines int `yaml:"writeback_goroutines"` 18 WriteBackBuffer int `yaml:"writeback_buffer"` 19 } 20 21 // RegisterFlagsWithPrefix adds the flags required to config this to the given FlagSet 22 func (cfg *BackgroundConfig) RegisterFlagsWithPrefix(prefix string, description string, f *flag.FlagSet) { 23 f.IntVar(&cfg.WriteBackGoroutines, prefix+"background.write-back-concurrency", 10, description+"At what concurrency to write back to cache.") 24 f.IntVar(&cfg.WriteBackBuffer, prefix+"background.write-back-buffer", 10000, description+"How many key batches to buffer for background write-back.") 25 } 26 27 type backgroundCache struct { 28 Cache 29 30 wg sync.WaitGroup 31 quit chan struct{} 32 bgWrites chan backgroundWrite 33 name string 34 35 droppedWriteBack prometheus.Counter 36 queueLength prometheus.Gauge 37 } 38 39 type backgroundWrite struct { 40 keys []string 41 bufs [][]byte 42 } 43 44 // NewBackground returns a new Cache that does stores on background goroutines. 45 func NewBackground(name string, cfg BackgroundConfig, cache Cache, reg prometheus.Registerer) Cache { 46 c := &backgroundCache{ 47 Cache: cache, 48 quit: make(chan struct{}), 49 bgWrites: make(chan backgroundWrite, cfg.WriteBackBuffer), 50 name: name, 51 droppedWriteBack: promauto.With(reg).NewCounter(prometheus.CounterOpts{ 52 Namespace: "cortex", 53 Name: "cache_dropped_background_writes_total", 54 Help: "Total count of dropped write backs to cache.", 55 ConstLabels: prometheus.Labels{"name": name}, 56 }), 57 58 queueLength: promauto.With(reg).NewGauge(prometheus.GaugeOpts{ 59 Namespace: "cortex", 60 Name: "cache_background_queue_length", 61 Help: "Length of the cache background write queue.", 62 ConstLabels: prometheus.Labels{"name": name}, 63 }), 64 } 65 66 c.wg.Add(cfg.WriteBackGoroutines) 67 for i := 0; i < cfg.WriteBackGoroutines; i++ { 68 go c.writeBackLoop() 69 } 70 71 return c 72 } 73 74 func (c *backgroundCache) writeBackLoop() { 75 defer c.wg.Done() 76 77 for { 78 select { 79 case bgWrite, ok := <-c.bgWrites: 80 if !ok { 81 return 82 } 83 c.queueLength.Sub(float64(len(bgWrite.keys))) 84 c.Cache.Store(context.Background(), bgWrite.keys, bgWrite.bufs) 85 86 case <-c.quit: 87 return 88 } 89 } 90 }