12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182 |
- package gcache
- import "sync"
- type call struct {
- wg sync.WaitGroup
- val interface{}
- err error
- }
- type Group struct {
- cache Cache
- mu sync.Mutex
- m map[interface{}]*call
- }
- func (g *Group) Do(key interface{}, fn func() (interface{}, error), isWait bool) (interface{}, bool, error) {
- g.mu.Lock()
- v, err := g.cache.get(key, true)
- if err == nil {
- g.mu.Unlock()
- return v, false, nil
- }
- if g.m == nil {
- g.m = make(map[interface{}]*call)
- }
- if c, ok := g.m[key]; ok {
- g.mu.Unlock()
- if !isWait {
- return nil, false, KeyNotFoundError
- }
- c.wg.Wait()
- return c.val, false, c.err
- }
- c := new(call)
- c.wg.Add(1)
- g.m[key] = c
- g.mu.Unlock()
- if !isWait {
- go g.call(c, key, fn)
- return nil, false, KeyNotFoundError
- }
- v, err = g.call(c, key, fn)
- return v, true, err
- }
- func (g *Group) call(c *call, key interface{}, fn func() (interface{}, error)) (interface{}, error) {
- c.val, c.err = fn()
- c.wg.Done()
- g.mu.Lock()
- delete(g.m, key)
- g.mu.Unlock()
- return c.val, c.err
- }
|