Skip to content

Commit be10acb

Browse files
committed
refactor common part into doNoChan
1 parent 8e5fd78 commit be10acb

File tree

1 file changed

+8
-18
lines changed

1 file changed

+8
-18
lines changed

singleflight/singleflight.go

+8-18
Original file line numberDiff line numberDiff line change
@@ -64,22 +64,7 @@ func (v RefCounter) Decrement() bool {
6464
// DoRefCount should NOT be mixed for same key with Do/DoChan to avoid race condition in calulating "shared" retiun value
6565
// The return value refCount maintains "reference counter" for multiple callers.
6666
func (g *Group) DoRefCount(key string, fn func() (interface{}, error)) (v interface{}, err error, refCount RefCounter) {
67-
g.mu.Lock()
68-
if g.m == nil {
69-
g.m = make(map[string]*call)
70-
}
71-
if c, ok := g.m[key]; ok {
72-
c.dups++
73-
g.mu.Unlock()
74-
c.wg.Wait()
75-
return c.val, c.err, RefCounter{ptr: &c.dups, zero: -1}
76-
}
77-
c := new(call)
78-
c.wg.Add(1)
79-
g.m[key] = c
80-
g.mu.Unlock()
81-
82-
g.doCall(c, key, fn)
67+
c := g.doNoChan(key, fn)
8368

8469
// use -1 instead of 0 because call.dups is initialized with 0,
8570
// in other words: for single caller RefCounter will hold value of 0
@@ -92,6 +77,11 @@ func (g *Group) DoRefCount(key string, fn func() (interface{}, error)) (v interf
9277
// original to complete and receives the same results.
9378
// The return value shared indicates whether v was given to multiple callers.
9479
func (g *Group) Do(key string, fn func() (interface{}, error)) (v interface{}, err error, shared bool) {
80+
c := g.doNoChan(key, fn)
81+
return c.val, c.err, c.dups > 0
82+
}
83+
84+
func (g *Group) doNoChan(key string, fn func() (interface{}, error)) *call {
9585
g.mu.Lock()
9686
if g.m == nil {
9787
g.m = make(map[string]*call)
@@ -100,15 +90,15 @@ func (g *Group) Do(key string, fn func() (interface{}, error)) (v interface{}, e
10090
c.dups++
10191
g.mu.Unlock()
10292
c.wg.Wait()
103-
return c.val, c.err, true
93+
return c
10494
}
10595
c := new(call)
10696
c.wg.Add(1)
10797
g.m[key] = c
10898
g.mu.Unlock()
10999

110100
g.doCall(c, key, fn)
111-
return c.val, c.err, c.dups > 0
101+
return c
112102
}
113103

114104
// DoChan is like Do but returns a channel that will receive the

0 commit comments

Comments
 (0)