github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/chat/unfurl/cache.go (about) 1 package unfurl 2 3 import ( 4 "sync" 5 "time" 6 7 lru "github.com/hashicorp/golang-lru" 8 "github.com/keybase/client/go/protocol/gregor1" 9 "github.com/keybase/clockwork" 10 ) 11 12 const defaultCacheLifetime = 10 * time.Minute 13 const defaultCacheSize = 1000 14 15 type cacheItem struct { 16 data interface{} 17 ctime gregor1.Time 18 } 19 20 type unfurlCache struct { 21 sync.Mutex 22 cache *lru.Cache 23 clock clockwork.Clock 24 } 25 26 func newUnfurlCache() *unfurlCache { 27 cache, err := lru.New(defaultCacheSize) 28 if err != nil { 29 panic(err) 30 } 31 return &unfurlCache{ 32 cache: cache, 33 clock: clockwork.NewRealClock(), 34 } 35 } 36 37 func (c *unfurlCache) setClock(clock clockwork.Clock) { 38 c.clock = clock 39 } 40 41 // get determines if the item is in the cache and newer than 10 42 // minutes. We don't want to cache this value indefinitely in case the page 43 // content changes. 44 func (c *unfurlCache) get(key string) (res cacheItem, ok bool) { 45 c.Lock() 46 defer c.Unlock() 47 48 item, ok := c.cache.Get(key) 49 if !ok { 50 return res, false 51 } 52 cacheItem, ok := item.(cacheItem) 53 if !ok { 54 return res, false 55 } 56 valid := c.clock.Now().Sub(cacheItem.ctime.Time()) <= defaultCacheLifetime 57 if !valid { 58 c.cache.Remove(key) 59 } 60 return cacheItem, valid 61 } 62 63 func (c *unfurlCache) put(key string, data interface{}) { 64 c.Lock() 65 defer c.Unlock() 66 c.cache.Add(key, cacheItem{ 67 data: data, 68 ctime: gregor1.ToTime(c.clock.Now()), 69 }) 70 }