singleflight 是什么
singleflight 直接翻译为"单(次)飞(行)"
举个例子,当程序中有读(如 Redis、MySQL、Http、RPC等)请求,且并发非常高的情况,使用 singleflight 能得到比较好的效果,它限制了同一时刻只有一个请求在执行,也就是并发永远为1
singleflight 的原理
将整个代码分成三块:
① 懒加载方式初始化 map;
② 如果当前 key 存在,即相同请求正在调用中,就等它完成,完成后直接使用它的 value 和 error;
③ 如果当前 key 不存在,即没有相同请求正在调用中,就创建一个 call 对象,并把它放进 map,接着执行 fn 函数,当函数执行完唤醒 waitGroup,并删除 map 相应的 key,返回 value 和 error
读可以抑制,写呢?
增强代码参考
package singleflight
import(
"sync"
)
type WriteGroup struct{
mu sync.Mutex
wgs map[string]*sync.WaitGroup
group Group
}
func(g *WriteGroup)Do(key string, fn func()error)error{
g.mu.Lock()
if g.wgs ==nil{
g.wgs =make(map[string]*sync.WaitGroup)
}
wg, ok := g.wgs[key]
if!ok {
wg =&sync.WaitGroup{}
wg.Add(1)
g.wgs[key]= wg
}
g.mu.Unlock()
if!ok {
err :=fn()
g.mu.Lock()
wg.Done()
delete(g.wgs, key)
g.mu.Unlock()
return err
}
wg.Wait()
_, err := g.group.Do(key,func()(interface{},error){
returnnil,fn()
})
return err
}