Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix single-flight ,and add UT description verification #69

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

opsoer
Copy link

@opsoer opsoer commented Mar 14, 2023

源码single-flight并不能保证fn只执行一次,可以用我提交的单测去跑一下,发现fn的执行次数并不是一次(而且每次运行次数还不确定),达不到防止缓存击穿的效果。
我的实现思路:map延迟一秒删除,第一个请求更新map,map里面的key全部一秒之后删除,一秒之内的所有请求都从map获取。一秒之后删除map里面一秒钟之前的数据,请求来了再重新更新map,重复如上 步骤。
注:删除数据不一定得一秒钟之后,可以一百毫秒,更具业务可以调整

@AyangHuang
Copy link

下面是发生这种情况的原因:

// Check the cache again because singleflight can only dedup calls
		// that overlap concurrently.  It's possible for 2 concurrent
		// requests to miss the cache, resulting in 2 load() calls.  An
		// unfortunate goroutine scheduling would result in this callback
		// being run twice, serially.  If we don't check the cache again,
		// cache.nbytes would be incremented below even though there will
		// be only one entry for this key.
		//
		// Consider the following serialized event ordering for two
		// goroutines in which this callback gets called twice for the
		// same key:
		// 1: Get("key")
		// 2: Get("key")
		// 1: lookupCache("key")
		// 2: lookupCache("key")
		// 1: load("key")
		// 2: load("key")
		// 1: loadGroup.Do("key", fn)
		// 1: fn()
		// 2: loadGroup.Do("key", fn)
		// 2: fn()

groupcache 给出的解决方法:

fn() {
    再次查询缓存是否已加载已加载直接返回
   执行 fn 的逻辑
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants