// call is an in-flight or completed Do call type call struct { wg sync.WaitGroup val interface{} err error }
// Group represents a class of work and forms a namespace in which // units of work can be executed with duplicate suppression. type Group struct { mu sync.Mutex // protects m m map[string]*call // lazily initialized }
// Do executes and returns the results of the given function, making // sure that only one execution is in-flight for a given key at a // time. If a duplicate comes in, the duplicate caller waits for the // original to complete and receives the same results. func(g *Group) Do(key string, fn func() (interface{}, error)) (interface{}, error) { // 加锁 g.mu.Lock() if g.m == nil { g.m = make(map[string]*call) } // 如果已经有 call in flight, then wait if c, ok := g.m[key]; ok { // 解锁 g.mu.Unlock() // 通过 wg 来等待, 因为另一个 g 已经对 wg.Add(1) 了 c.wg.Wait() return c.val, c.err } c := new(call) c.wg.Add(1) g.m[key] = c // 这里不解锁,其他的 g 会先在 g.mu.Lock() 等待 g.mu.Unlock()