Skip to content

Latest commit

 

History

History
75 lines (62 loc) · 1.59 KB

README.md

File metadata and controls

75 lines (62 loc) · 1.59 KB

Singleflight

https://pkg.go.dev/golang.org/x/[email protected]/singleflight

runtime

https://pkg.go.dev/runtime

  • runtime.Gosched()

    讓出CPU給其他goroutine執行

  • runtime.Goexit()

    結束當前goroutine

  • runtime.GOMAXPROCS()

    GOMAXPROCS sets the maximum number of CPUs that can be executing simultaneously and returns the previous setting. It defaults to the value of runtime.NumCPU. If n < 1, it does not change the current setting. This call will go away when the scheduler improves.

    number of processors used, or /sched/gomaxprocs:threads

Do

func (g *Group) Do(key string, fn func() (interface{}, error)) (v interface{}, err error, shared bool) {
	g.mu.Lock()
	if g.m == nil {
		g.m = make(map[string]*call)
	}
	if c, ok := g.m[key]; ok {
		c.dups++
		g.mu.Unlock()
		c.wg.Wait()

		if e, ok := c.err.(*panicError); ok {
			panic(e)
		} else if c.err == errGoexit {
			runtime.Goexit()
		}
		return c.val, c.err, true
	}
	c := new(call)
	c.wg.Add(1)
	g.m[key] = c
	g.mu.Unlock()

	g.doCall(c, key, fn)
	return c.val, c.err, c.dups > 0
}

可以簡化code,比較好去理解它的概念

參考 https://github.com/golang/groupcache/blob/master/singleflight/singleflight.go

func (g *Group) Do(key string, fn func() (any, error)) (any, 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
}