From 89f41bddfe320d1474dcd92ff8deeb6e7e9fe825 Mon Sep 17 00:00:00 2001 From: Daniel Nephin Date: Thu, 2 Apr 2020 18:42:29 -0400 Subject: [PATCH] Remove TTL from cacheEntryExpiry This should very slightly reduce the amount of memory required to store each item in the cache. It will also enable setting different TTLs based on the type of result. For example we may want to use a shorter TTL when the result indicates the resource does not exist, as storing these types of records could easily lead to a DOS caused by OOM. --- agent/cache/cache.go | 18 ++++-------------- agent/cache/entry.go | 13 ++++++------- 2 files changed, 10 insertions(+), 21 deletions(-) diff --git a/agent/cache/cache.go b/agent/cache/cache.go index 54294eb07f..66146610f2 100644 --- a/agent/cache/cache.go +++ b/agent/cache/cache.go @@ -317,7 +317,7 @@ RETRY_GET: // Touch the expiration and fix the heap. c.entriesLock.Lock() - entry.Expiry.Reset() + entry.Expiry.Update(tEntry.Opts.LastGetTTL) c.entriesExpiryHeap.Fix(entry.Expiry) c.entriesLock.Unlock() @@ -582,11 +582,8 @@ func (c *Cache) fetch(tEntry typeEntry, key string, r Request, allowNew bool, at // initial expiry information and insert. If we're already in // the heap we do nothing since we're reusing the same entry. if newEntry.Expiry == nil || newEntry.Expiry.HeapIndex == -1 { - newEntry.Expiry = &cacheEntryExpiry{ - Key: key, - TTL: tEntry.Opts.LastGetTTL, - } - newEntry.Expiry.Reset() + newEntry.Expiry = &cacheEntryExpiry{Key: key} + newEntry.Expiry.Update(tEntry.Opts.LastGetTTL) heap.Push(c.entriesExpiryHeap, newEntry.Expiry) } @@ -717,13 +714,6 @@ func (c *Cache) Close() error { // AutoEncrypt.TLS is turned on. The cache itself cannot fetch that the first // time because it requires a special RPCType. Subsequent runs are fine though. func (c *Cache) Prepopulate(t string, res FetchResult, dc, token, k string) error { - // Check the type that we're prepolulating - c.typesLock.RLock() - tEntry, ok := c.types[t] - c.typesLock.RUnlock() - if !ok { - return fmt.Errorf("unknown type in cache: %s", t) - } key := makeEntryKey(t, dc, token, k) newEntry := cacheEntry{ Valid: true, @@ -732,7 +722,7 @@ func (c *Cache) Prepopulate(t string, res FetchResult, dc, token, k string) erro Index: res.Index, FetchedAt: time.Now(), Waiter: make(chan struct{}), - Expiry: &cacheEntryExpiry{Key: key, TTL: tEntry.Opts.LastGetTTL}, + Expiry: &cacheEntryExpiry{Key: key}, } c.entriesLock.Lock() c.entries[key] = newEntry diff --git a/agent/cache/entry.go b/agent/cache/entry.go index dfeb982e00..9d7678a056 100644 --- a/agent/cache/entry.go +++ b/agent/cache/entry.go @@ -47,15 +47,14 @@ type cacheEntry struct { // entry. Any modifications to this struct should be done only while // the Cache entriesLock is held. type cacheEntryExpiry struct { - Key string // Key in the cache map - Expires time.Time // Time when entry expires (monotonic clock) - TTL time.Duration // TTL for this entry to extend when resetting - HeapIndex int // Index in the heap + Key string // Key in the cache map + Expires time.Time // Time when entry expires (monotonic clock) + HeapIndex int // Index in the heap } -// Reset resets the expiration to be the ttl duration from now. -func (e *cacheEntryExpiry) Reset() { - e.Expires = time.Now().Add(e.TTL) +// Update the expiry to d time from now. +func (e *cacheEntryExpiry) Update(d time.Duration) { + e.Expires = time.Now().Add(d) } // expiryHeap is a heap implementation that stores information about