Created
January 15, 2021 06:30
-
-
Save daydaygo/800b895049562defdc1127520c3d8c97 to your computer and use it in GitHub Desktop.
singleflight
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://github.com/geektutu/7days-golang/tree/master/gee-cache/day6-single-flight/geecache/singleflight | |
package singleflight | |
import "sync" | |
// 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) | |
} | |
if c, ok := g.m[key]; ok { | |
g.mu.Unlock() | |
c.wg.Wait() | |
return c.val, c.err | |
} | |
c := new(call) | |
c.wg.Add(1) | |
g.m[key] = c | |
g.mu.Unlock() | |
c.val, c.err = fn() | |
c.wg.Done() | |
g.mu.Lock() | |
delete(g.m, key) | |
g.mu.Unlock() | |
return c.val, c.err | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment