diff options
Diffstat (limited to 'cache/cache.go')
-rw-r--r-- | cache/cache.go | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/cache/cache.go b/cache/cache.go index 0f4dde4..efa404d 100644 --- a/cache/cache.go +++ b/cache/cache.go @@ -38,6 +38,8 @@ type Cache struct { keys []uint32 mu sync.RWMutex now func() time.Time + queue chan func() + wg sync.WaitGroup } // Value wraps a DNS message stored in the cache. @@ -139,8 +141,10 @@ func newCache(capacity int, client *dnsutil.Client, backend Backend, now func() now: now, capacity: capacity, values: make(map[uint32]Value, capacity), + queue: make(chan func(), 1024), } c.load(backend) + go c.readQueue() return c } @@ -176,6 +180,12 @@ func (c *Cache) load(backend Backend) { c.backend = backend } +// Close consumes any outstanding cache operations. +func (c *Cache) Close() error { + c.wg.Wait() + return nil +} + // Get returns the DNS message associated with key. func (c *Cache) Get(key uint32) (*dns.Msg, bool) { v, ok := c.getValue(key) @@ -194,11 +204,10 @@ func (c *Cache) getValue(key uint32) (*Value, bool) { } if c.isExpired(&v) { if !c.prefetch() { - go c.evictWithLock(key) + c.enqueue(func() { c.evictWithLock(key) }) return nil, false } - // Refresh and return a stale value - go c.refresh(key, v.msg) + c.enqueue(func() { c.refresh(key, v.msg) }) } return &v, true } @@ -320,6 +329,18 @@ func (c *Cache) isExpired(v *Value) bool { return c.now().After(expiresAt) } +func (c *Cache) enqueue(op func()) { + c.wg.Add(1) + c.queue <- op +} + +func (c *Cache) readQueue() { + for op := range c.queue { + op() + c.wg.Done() + } +} + func canCache(msg *dns.Msg) bool { if dnsutil.MinTTL(msg) == 0 { return false |