10.go Open Source Groupcache Project Toad Note--singleflight

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

10.go Open Source Groupcache Project Toad Note--singleflight

1 singleflight

This package mainly implements a merge operation interface.

1.1 First define a callback function structure call

type call struct {
    //类似javaCountdownLatch
    wg  sync.WaitGroup
    // 回调函数
    val interface{}
    // error
    err error
}

1.2 Defining a group structure

Type Group struct {

Musync. Mutex//Protects M

M map[string]*call//lazily initialized

}

Go Use the case of the first letter to determine whether externally visible, uppercase outer visible, lowercase outside is not visible, such as the above Group in the external practical Singleflght The package is accessible, while the Pager can't .

1.3 Do function

The main interface of the package, used to send query requests to other nodes, merging requests for the same key, reducing the potential for hot spots, such as my request for key= "123" data, there are many same key requests when there is no return, and there is no need to post at this time, Just wait for the result to be returned the first time.

Return is a inferace and error. The entry parameter is a key and a function.

func (g *Group) Do(key string, fn func() (interface{}, error)) (interface{}, error) {
    // 首先获取group
    g.mu.Lock()
    // 映射表不存在就创建1
    if g.m == nil {
        g.m = make(map[string]*call)
    }
    // 判断要查询某个key的请求是否已经在处理了
    if c, ok := g.m[key]; ok {
        // 已经在处理了就释放groupwaitwg上,我们看到wg1是在某个时间段内第一次请求时加的
        // 并且在完成fn操作返回后会wg done,那时wait等待就会返回,直接返回第一次请求的结果
        g.mu.Unlock()
        c.wg.Wait()
        return c.val, c.err
    }
    // 如果没有在处理,则创建回调,wg1,把回调存到m中表示已经有在请求了,释放锁
    c := new(call)
    c.wg.Add(1)
    g.m[key] = c
    g.mu.Unlock()
    // 执行fn,释放wg
    c.val, c.err = fn()
    c.wg.Done()
    // 加锁将请求从m中删除,表示请求已经做好了
    g.mu.Lock()
    delete(g.m, key)
    g.mu.Unlock()
    return c.val, c.err
}

2 Singleflight_test

2.1 Testdo

Define a variable G for Group type

Call the Do function. The return value is assigned a value of V.

Determine if V is bar (string)

2.2 Testdoerr

Define a variable G for Group type

Add a custom error as follows:

Someerr: = errors. New ("Someerror")

Then call the Do function. Returns a custom error.

It then determines whether the error returned is correct.

2.3 testdodupsuppress

Define a variable G for Group type

A return function, used with the Detect 10 loop, is also called only once.

fn: = func () (interface{}, error) {

Atomic. AddInt32 (&calls,1)

Return<-c, Nil

}

Defines a constant of 10.

Cycle 10 times

Each WG. ADD (1), then concurrent go func ()

Then wait for 100ms to allow Goroutings to block for a while.

The function returns a channel variable.

Assign a value bar to the channel variable.

2.4 Test Results

Test as follows

= = = RUN Testdo

---pass:testdo (0.00s)

= = = RUN Testdoerr

---pass:testdoerr (0.00s)

= = = RUN testdodupsuppress

---pass:testdodupsuppress (0.10s)

PASS

OK Test 0.227s

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.