muesli / cache2go

Concurrency-safe Go caching library with expiration capabilities and access counters
Other
2.11k stars 518 forks source link

if registered dataload, Value() not thread safe #35

Open winxxp opened 5 years ago

winxxp commented 5 years ago
// Value returns an item from the cache and marks it to be kept alive. You can
// pass additional arguments to your DataLoader callback function.
func (table *CacheTable) Value(key interface{}, args ...interface{}) (*CacheItem, error) {
    table.RLock()
    r, ok := table.items[key]
    loadData := table.loadData
    table.RUnlock()

    if ok {
        // Update access counter and timestamp.
        r.KeepAlive()
        return r, nil
    }

    // Item doesn't exist in cache. Try and fetch it with a data-loader.
    if loadData != nil {
        item := loadData(key, args...)
        if item != nil {
            table.Add(key, item.lifeSpan, item.data)
            return item, nil
        }

        return nil, ErrKeyNotFoundOrLoadable
    }

    return nil, ErrKeyNotFound
}
muesli commented 5 years ago

Can you elaborate a bit more?

winxxp commented 5 years ago

if value is file handle, key is filename, so kV is filename -> file handle. eg. thread 1,2,... call Value(filename) , and filename is not in cache, so all thread will call loadData to open same filename.