diff --git a/go.mod b/go.mod index 79d8a009..ca3e158a 100644 --- a/go.mod +++ b/go.mod @@ -59,6 +59,7 @@ require ( go.uber.org/zap v1.13.0 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 golang.org/x/net v0.0.0-20200707034311-ab3426394381 + golang.org/x/sync v0.0.0-20201207232520-09787c993a3a // indirect golang.org/x/sys v0.0.0-20200523222454-059865788121 // indirect golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1 diff --git a/go.sum b/go.sum index 00a3830a..83915dd4 100644 --- a/go.sum +++ b/go.sum @@ -605,6 +605,8 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a h1:DcqTD9SDLc+1P/r1EmRBwnVsrOwW+kk2vWf9n+1sGhs= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180622082034-63fc586f45fe/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= diff --git a/registry/cache/cache.go b/registry/cache/cache.go index 2799f2d4..805fffb3 100644 --- a/registry/cache/cache.go +++ b/registry/cache/cache.go @@ -10,6 +10,7 @@ import ( "github.com/micro/go-micro/v2/logger" "github.com/micro/go-micro/v2/registry" util "github.com/micro/go-micro/v2/util/registry" + "golang.org/x/sync/singleflight" ) // Cache is the registry cache interface @@ -46,6 +47,8 @@ type cache struct { // used to hold onto the cache // in failure state status error + // used to prevent cache breakdwon + sg singleflight.Group } var ( @@ -132,7 +135,10 @@ func (c *cache) get(service string) ([]*registry.Service, error) { // get does the actual request for a service and cache it get := func(service string, cached []*registry.Service) ([]*registry.Service, error) { // ask the registry - services, err := c.Registry.GetService(service) + val, err, _ := c.sg.Do(service, func() (interface{}, error) { + return c.Registry.GetService(service) + }) + services, _ := val.([]*registry.Service) if err != nil { // check the cache if len(cached) > 0 {