10.go开源groupcache项目笔记——singleFlight
来源:互联网 发布:黑死馆杀人事件知乎 编辑:程序博客网 时间:2024/06/08 00:40
10.go开源groupcache项目笔记——singleFlight
1 singleFlight
这个包主要实现了一个可合并操作的接口
1.1 先定义一个回调函数结构call
type call struct {
//
类似
java
的
CountdownLatch
的
wg sync.WaitGroup
//
回调函数
val interface{}
// error
err error
}
1.2 定义一个Group结构体
type Group struct {
musync.Mutex // protects m
m map[string]*call // lazily initialized
}
Go使用开头字母大小写判断是否外部可见,大写外部可见,小写外部不可见,比如上面的Group在外部实用singleflght包是可以访问到的,而call不能.
1.3 Do函数
包的主要接口,用于向其他节点发送查询请求时,合并相同key的请求,减少热点可能带来的麻烦,比如说我请求key="123"的数据,在没有返回的时候又有很多相同key的请求,而此时后面的没有必要发,只要等待第一次返回的结果即可.
返回是一个inferace和error.入参是一个key和一个函数。
func (g *Group) Do(key string, fn func() (interface{}, error)) (interface{}, error) {
//
首先获取
group
锁
g.mu.Lock()
//
映射表不存在就创建
1
个
if g.m == nil {
g.m = make(map[string]*call)
}
//
判断要查询某个
key
的请求是否已经在处理了
if c, ok := g.m[key]; ok {
//
已经在处理了
就释放
group
锁
并
wait
在
wg
上,我们看到
wg
加
1
是在某个时间段内第一次请求时加的
//
并且在完成
fn
操作返回后会
wg done
,那时
wait
等待就会返回,直接返回第一次请求的结果
g.mu.Unlock()
c.wg.Wait()
return c.val, c.err
}
//
如果没有在处理,则创建回调,
wg
加
1
,把回调存到
m
中表示已经有在请求了,释放锁
c := new(call)
c.wg.Add(1)
g.m[key] = c
g.mu.Unlock()
//
执行
fn
,释放
wg
c.val, c.err = fn()
c.wg.Done()
//
加锁将请求从
m
中删除,表示请求已经做好了
g.mu.Lock()
delete(g.m, key)
g.mu.Unlock()
return c.val, c.err
}
2 Singleflight_test
2.1 TestDo
定义一个变量g 为Group类型
调用Do函数。返回值赋值为v.
判断v是否为bar (string)
2.2 TestDoErr
定义一个变量g 为Group类型
增加一个自定义错误如下:
someErr := errors.New("Someerror")
然后调用Do函数。返回为自定义的错误。
然后判断返回的错误是否正确。
2.3 TestDoDupSuppress
定义一个变量g 为Group类型
一个返回函数,用与检测10循环也只调用了一次。
fn := func() (interface{}, error) {
atomic.AddInt32(&calls,1)
return<-c, nil
}
定义一个常数10.
循环10次
每次wg.Add(1),然后并发go func()
然后等待100ms让goroutings可以阻塞一会。
函数返回的是一个通道变量。
给通道变量赋值bar.
2.4 测试结果
测试如下
=== RUN TestDo
--- PASS: TestDo (0.00s)
=== RUN TestDoErr
--- PASS: TestDoErr (0.00s)
=== RUN TestDoDupSuppress
--- PASS: TestDoDupSuppress(0.10s)
PASS
ok test 0.227s
- 10.go开源groupcache项目笔记——singleFlight
- 1.go开源groupcache项目——groupcache介绍
- 14.go开源groupcache项目笔记——peers代码
- 15.go开源groupcache项目笔记——sinks代码
- 4.go开源groupcache项目笔记——关于strconv
- 5.go开源groupcache项目笔记——关于testing
- 6.go开源groupcache项目笔记——consistenthash_test代码
- 8.go开源groupcache项目笔记——groupcachepb代码
- 9.go开源groupcache项目笔记——lru代码
- 11.go开源groupcache项目笔记——testpb代码
- 12.go开源groupcache项目笔记——byteview代码
- 16.go开源groupcache项目笔记——部署
- 7.go开源groupcache项目笔记——关于gocode代码自动补齐
- 13.go开源groupcache项目笔记——byteview_test测试代码
- 2.go开源groupcache项目——关于protobuf
- 3.go开源groupcache项目——consistenthash代码
- 10.go开源cache2go项目笔记——mycachedapp调用
- 2.go开源cache2go项目笔记——项目介绍
- CodeForces
- spring框架
- JAVA中继承和接口
- 第十一课 使用子查询
- redis安装make的时候 gcc找不到命令
- 10.go开源groupcache项目笔记——singleFlight
- Scrapy安装错误:Microsoft Visual C++ 14.0 is required...
- 姓名,性别,年龄的输出
- HDU5762[Teacher Bo]--暴力枚举
- 11.go开源groupcache项目笔记——testpb代码
- 防止过拟合的处理方法
- you-get 下载暂停
- 12.go开源groupcache项目笔记——byteview代码
- Python Multi-Processing多线程编程