karlseguin / ccache

A golang LRU Cache for high concurrency
MIT License
1.29k stars 120 forks source link

Bug report: item leak when c.promotables is busy #64

Closed chenqiuhao1997 closed 3 years ago

chenqiuhao1997 commented 3 years ago

When setting a new key, Cache would use c.promote to add new item in c.list. But when c.promotables is full, c.promote would do nothing, which means new item would not be added into c.list. That would cause item leak until a get operation when c.promotables is not full. If there is no operation about this key in the future before c.promote successfully takes effect, the memory of the item would never be released because of the reference from the map.

// https://github.com/karlseguin/ccache/blob/master/cache.go

// Set the value in the cache for the specified duration
func (c *Cache) Set(key string, value interface{}, duration time.Duration) {
    c.set(key, value, duration, false)
}

func (c *Cache) set(key string, value interface{}, duration time.Duration, track bool) *Item {
    item, existing := c.bucket(key).set(key, value, duration, track)
    if existing != nil {
        c.deletables <- existing
    }
    c.promote(item)
    return item
}

func (c *Cache) promote(item *Item) {
    select {
    case c.promotables <- item:
    default:
    }

}
karlseguin commented 3 years ago

Thanks, you're right. Fixed