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  }