github.com/tiagovtristao/plz@v13.4.0+incompatible/src/cache/async_cache.go (about) 1 package cache 2 3 import ( 4 "sync" 5 6 "github.com/thought-machine/please/src/core" 7 ) 8 9 // An asyncCache is a wrapper around a Cache interface that handles incoming 10 // store requests asynchronously and attempts to return immediately. 11 // The requests are handled on an internal queue, if that fills up then 12 // incoming requests will start to block again until it empties. 13 // Retrieval requests are still handled synchronously. 14 type asyncCache struct { 15 requests chan cacheRequest 16 realCache core.Cache 17 wg sync.WaitGroup 18 } 19 20 // A cacheRequest models an incoming cache request on our queue. 21 type cacheRequest struct { 22 target *core.BuildTarget 23 key []byte 24 files []string 25 file string 26 } 27 28 func newAsyncCache(realCache core.Cache, config *core.Configuration) core.Cache { 29 c := &asyncCache{ 30 requests: make(chan cacheRequest), 31 realCache: realCache, 32 } 33 c.wg.Add(config.Cache.Workers) 34 for i := 0; i < config.Cache.Workers; i++ { 35 go c.run() 36 } 37 return c 38 } 39 40 func (c *asyncCache) Store(target *core.BuildTarget, key []byte, files ...string) { 41 c.requests <- cacheRequest{ 42 target: target, 43 key: key, 44 files: files, 45 } 46 } 47 48 func (c *asyncCache) StoreExtra(target *core.BuildTarget, key []byte, file string) { 49 c.requests <- cacheRequest{ 50 target: target, 51 key: key, 52 file: file, 53 } 54 } 55 56 func (c *asyncCache) Retrieve(target *core.BuildTarget, key []byte) bool { 57 return c.realCache.Retrieve(target, key) 58 } 59 60 func (c *asyncCache) RetrieveExtra(target *core.BuildTarget, key []byte, file string) bool { 61 return c.realCache.RetrieveExtra(target, key, file) 62 } 63 64 func (c *asyncCache) Clean(target *core.BuildTarget) { 65 c.realCache.Clean(target) 66 } 67 68 func (c *asyncCache) CleanAll() { 69 c.realCache.CleanAll() 70 } 71 72 func (c *asyncCache) Shutdown() { 73 log.Info("Shutting down cache workers...") 74 close(c.requests) 75 c.wg.Wait() 76 log.Debug("Shut down all cache workers") 77 } 78 79 // run implements the actual async logic. 80 func (c *asyncCache) run() { 81 for r := range c.requests { 82 if r.file != "" { 83 c.realCache.StoreExtra(r.target, r.key, r.file) 84 } else { 85 c.realCache.Store(r.target, r.key, r.files...) 86 } 87 } 88 c.wg.Done() 89 }