fastcache icon indicating copy to clipboard operation
fastcache copied to clipboard

Should add LoadOrStore() like sync.Map?

Open yutingjin opened this issue 6 years ago • 3 comments

just like the sync.Map: vv, ok := c.LoadOrStore(k, v) then we could know if the key exists in the concurrent race case, and to avoid duplicated set operation.

yutingjin avatar Dec 19 '18 07:12 yutingjin

Could you elaborate the purpose of the feature? The usual workflow for the cache is:

v := c.Get(nil, k)
if len(v) == 0 {
    v = createValue()
    c.Set(k, v)
}

The c.LoadOrStore would look like:

v = createValue()  // This line may be called multiple times by concurrent goroutines
vv, ok := c.LoadOrStore(k, v)

It is unclear which problem the LoadOrStore solves in this case. Probably, c.GetOrCreate(key, createValue) must be implemented instead for thundering herd problem?

// GetOrCreate appends value for the given key to dst and returns the result.
//
// createValue is called if the value for the given key is missing.
// createValue must create the value, append it to dst and return the result.
// It is guranteed that createValue is called only once by concurrent
// goroutines for the missing key.
func (c *Cache) GetOrCreate(dst []byte, key []byte, createValue func(dst []byte) []byte) []byte

valyala avatar Dec 19 '18 20:12 valyala

there is a case in my project, the queue message need to be checked if duplicated handled in multiple goroutines. So i cached the message id, and check if it exists before handling the new message.

// get message id if exists
qMsgCache.Get(v, k)
// set into cache ASAP
qMsgCache.Set(k, vv)
// check if load, but the cache may be refreshed in another goroutine
if len(v) > 0 {
    // ignore the duplicate message
}

But if two same message received by two handlers in different goroutines at the same time, and found there is nothing in cache. So they both set id into it, and begin to handle the message.

So that is why i want a loadOrStore function, which could make sure the cached object unique in multiple goroutines cases.

Thanks.

yutingjin avatar Dec 24 '18 01:12 yutingjin

Hi @yutingjin @valyala . Is this interface currently implemented?

Our scenario is that when we set kv, we need to check whether the key exists, and if it does not exist, then set, and return it directly if it exists, so as to avoid the cache being written to dirty data.

more details.

We have a concurrent scenario of get-set(1) and get-update-set(2), when both get the data first, the 2 will set first after the update is completed, and then the 1 set, which will cause dirty data in the cache.

So if we have a LoadOrStore or GetOrCreate interface, we can avoid the above problems.

Thanks all.

fynnss avatar Nov 17 '23 09:11 fynnss