From 49b71c05ecf608259ab1a585d8820e34b14c5b91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=BF=97=E4=BF=A1?= Date: Wed, 9 Dec 2020 09:49:46 +0800 Subject: [PATCH 01/39] fix: add health check blace list --- cluster/cluster_impl/base_cluster_invoker.go | 26 ++++++++-- .../healthcheck/default_health_check.go | 2 +- .../router/healthcheck/health_check_route.go | 8 ++- common/constant/key.go | 5 ++ config/reference_config.go | 52 ++++++++++--------- protocol/rpc_status.go | 31 +++++++++++ registry/directory/directory.go | 2 + 7 files changed, 93 insertions(+), 33 deletions(-) diff --git a/cluster/cluster_impl/base_cluster_invoker.go b/cluster/cluster_impl/base_cluster_invoker.go index ed30559ed3..891b189ba0 100644 --- a/cluster/cluster_impl/base_cluster_invoker.go +++ b/cluster/cluster_impl/base_cluster_invoker.go @@ -124,15 +124,23 @@ func (invoker *baseClusterInvoker) doSelectInvoker(lb cluster.LoadBalance, invoc logger.Errorf("the invokers of %s is nil. ", invocation.Invoker().GetUrl().ServiceKey()) return nil } + refreshBlackList() if len(invokers) == 1 { - return invokers[0] + if invokers[0].IsAvailable() { + return invokers[0] + } + protocol.SetInvokerUnhealthyStatus(invokers[0]) + logger.Errorf("the invokers of %s is nil. ", invocation.Invoker().GetUrl().ServiceKey()) + return nil } selectedInvoker := lb.Select(invokers, invocation) - //judge to if the selectedInvoker is invoked - + //judge to if the selectedInvoker is invoked and available if (!selectedInvoker.IsAvailable() && invoker.availablecheck) || isInvoked(selectedInvoker, invoked) { + // 拉黑当前 + protocol.SetInvokerUnhealthyStatus(selectedInvoker) + // do reselect var reslectInvokers []protocol.Invoker @@ -140,6 +148,8 @@ func (invoker *baseClusterInvoker) doSelectInvoker(lb cluster.LoadBalance, invoc if !invoker.IsAvailable() { logger.Infof("the invoker of %s is not available, maybe some network error happened or the server is shutdown.", invoker.GetUrl().Ip) + // 拉黑reselect + protocol.SetInvokerUnhealthyStatus(invoker) continue } @@ -194,3 +204,13 @@ func getLoadBalance(invoker protocol.Invoker, invocation protocol.Invocation) cl } return extension.GetLoadbalance(lb) } + +func refreshBlackList() { + ivks := protocol.GetBlackListInvokers(constant.DEFAULT_BLACK_LIST_RECOVER_BLOCK) + logger.Debug("blackList len = ", len(ivks)) + for i, _ := range ivks { + if ivks[i].(protocol.Invoker).IsAvailable() { + protocol.RemoveInvokerUnhealthyStatus(ivks[i]) + } + } +} diff --git a/cluster/router/healthcheck/default_health_check.go b/cluster/router/healthcheck/default_health_check.go index 3effd779c9..a59e58ff61 100644 --- a/cluster/router/healthcheck/default_health_check.go +++ b/cluster/router/healthcheck/default_health_check.go @@ -48,7 +48,7 @@ type DefaultHealthChecker struct { // IsHealthy evaluates the healthy state on the given Invoker based on the number of successive bad request // and the current active request func (c *DefaultHealthChecker) IsHealthy(invoker protocol.Invoker) bool { - if !invoker.IsAvailable() { + if !protocol.GetInvokerHealthyStatus(invoker){ return false } diff --git a/cluster/router/healthcheck/health_check_route.go b/cluster/router/healthcheck/health_check_route.go index 1a878af212..42a802f947 100644 --- a/cluster/router/healthcheck/health_check_route.go +++ b/cluster/router/healthcheck/health_check_route.go @@ -32,9 +32,8 @@ import ( ) const ( - HEALTH_ROUTE_ENABLED_KEY = "health.route.enabled" - healthy = "healthy" - name = "health-check-router" + healthy = "healthy" + name = "health-check-router" ) // HealthCheckRouter provides a health-first routing mechanism through HealthChecker @@ -48,7 +47,7 @@ type HealthCheckRouter struct { func NewHealthCheckRouter(url *common.URL) (router.PriorityRouter, error) { r := &HealthCheckRouter{ url: url, - enabled: url.GetParamBool(HEALTH_ROUTE_ENABLED_KEY, false), + enabled: url.GetParamBool(constant.HEALTH_ROUTE_ENABLED_KEY, false), } if r.enabled { checkerName := url.GetParam(constant.HEALTH_CHECKER, constant.DEFAULT_HEALTH_CHECKER) @@ -87,7 +86,6 @@ func (r *HealthCheckRouter) Pool(invokers []protocol.Invoker) (router.AddrPool, rb[healthy].Add(uint32(i)) } } - return rb, nil } diff --git a/common/constant/key.go b/common/constant/key.go index 9525511cda..b10d12d798 100644 --- a/common/constant/key.go +++ b/common/constant/key.go @@ -89,6 +89,8 @@ const ( RETRY_PERIOD_KEY = "retry.period" RETRY_TIMES_KEY = "retry.times" CYCLE_REPORT_KEY = "cycle.report" + DEFAULT_BLACK_LIST_RECOVER_BLOCK = 10 + ) const ( @@ -238,6 +240,9 @@ const ( // Attachment key in context in invoker AttachmentKey = "attachment" + + // HEALTH_ROUTE_ENABLED_KEY defines if use health router + HEALTH_ROUTE_ENABLED_KEY = "health.route.enabled" ) const ( diff --git a/config/reference_config.go b/config/reference_config.go index 2e914ac9a7..53433100f3 100644 --- a/config/reference_config.go +++ b/config/reference_config.go @@ -41,30 +41,31 @@ import ( // ReferenceConfig is the configuration of service consumer type ReferenceConfig struct { - context context.Context - pxy *proxy.Proxy - id string - InterfaceName string `required:"true" yaml:"interface" json:"interface,omitempty" property:"interface"` - Check *bool `yaml:"check" json:"check,omitempty" property:"check"` - Url string `yaml:"url" json:"url,omitempty" property:"url"` - Filter string `yaml:"filter" json:"filter,omitempty" property:"filter"` - Protocol string `default:"dubbo" yaml:"protocol" json:"protocol,omitempty" property:"protocol"` - Registry string `yaml:"registry" json:"registry,omitempty" property:"registry"` - Cluster string `yaml:"cluster" json:"cluster,omitempty" property:"cluster"` - Loadbalance string `yaml:"loadbalance" json:"loadbalance,omitempty" property:"loadbalance"` - Retries string `yaml:"retries" json:"retries,omitempty" property:"retries"` - Group string `yaml:"group" json:"group,omitempty" property:"group"` - Version string `yaml:"version" json:"version,omitempty" property:"version"` - ProvideBy string `yaml:"provide_by" json:"provide_by,omitempty" property:"provide_by"` - Methods []*MethodConfig `yaml:"methods" json:"methods,omitempty" property:"methods"` - Async bool `yaml:"async" json:"async,omitempty" property:"async"` - Params map[string]string `yaml:"params" json:"params,omitempty" property:"params"` - invoker protocol.Invoker - urls []*common.URL - Generic bool `yaml:"generic" json:"generic,omitempty" property:"generic"` - Sticky bool `yaml:"sticky" json:"sticky,omitempty" property:"sticky"` - RequestTimeout string `yaml:"timeout" json:"timeout,omitempty" property:"timeout"` - ForceTag bool `yaml:"force.tag" json:"force.tag,omitempty" property:"force.tag"` + context context.Context + pxy *proxy.Proxy + id string + InterfaceName string `required:"true" yaml:"interface" json:"interface,omitempty" property:"interface"` + Check *bool `yaml:"check" json:"check,omitempty" property:"check"` + Url string `yaml:"url" json:"url,omitempty" property:"url"` + Filter string `yaml:"filter" json:"filter,omitempty" property:"filter"` + Protocol string `default:"dubbo" yaml:"protocol" json:"protocol,omitempty" property:"protocol"` + Registry string `yaml:"registry" json:"registry,omitempty" property:"registry"` + Cluster string `yaml:"cluster" json:"cluster,omitempty" property:"cluster"` + Loadbalance string `yaml:"loadbalance" json:"loadbalance,omitempty" property:"loadbalance"` + Retries string `yaml:"retries" json:"retries,omitempty" property:"retries"` + Group string `yaml:"group" json:"group,omitempty" property:"group"` + Version string `yaml:"version" json:"version,omitempty" property:"version"` + ProvideBy string `yaml:"provide_by" json:"provide_by,omitempty" property:"provide_by"` + Methods []*MethodConfig `yaml:"methods" json:"methods,omitempty" property:"methods"` + Async bool `yaml:"async" json:"async,omitempty" property:"async"` + Params map[string]string `yaml:"params" json:"params,omitempty" property:"params"` + invoker protocol.Invoker + urls []*common.URL + Generic bool `yaml:"generic" json:"generic,omitempty" property:"generic"` + Sticky bool `yaml:"sticky" json:"sticky,omitempty" property:"sticky"` + RequestTimeout string `yaml:"timeout" json:"timeout,omitempty" property:"timeout"` + ForceTag bool `yaml:"force.tag" json:"force.tag,omitempty" property:"force.tag"` + HealthCheckEnable bool `yaml:"health_check" json:"health_check,omitempty" property:"health_check"` } // nolint @@ -104,6 +105,9 @@ func (c *ReferenceConfig) Refer(_ interface{}) { if c.ForceTag { cfgURL.AddParam(constant.ForceUseTag, "true") } + if c.HealthCheckEnable { + cfgURL.AddParam(constant.HEALTH_ROUTE_ENABLED_KEY, "true") + } if c.Url != "" { // 1. user specified URL, could be peer-to-peer address, or register center's address. urlStrings := gxstrings.RegSplit(c.Url, "\\s*[;]+\\s*") diff --git a/protocol/rpc_status.go b/protocol/rpc_status.go index 8d443e84f0..7a915f4f5a 100644 --- a/protocol/rpc_status.go +++ b/protocol/rpc_status.go @@ -30,6 +30,7 @@ import ( var ( methodStatistics sync.Map // url -> { methodName : RPCStatus} serviceStatistic sync.Map // url -> RPCStatus + invokerBlackList sync.Map // store unhealthy url blackList ) // RPCStatus is URL statistics. @@ -181,4 +182,34 @@ func CleanAllStatus() { return true } serviceStatistic.Range(delete2) + delete3 := func(key, _ interface{}) bool { + invokerBlackList.Delete(key) + return true + } + invokerBlackList.Range(delete3) +} + +func GetInvokerHealthyStatus(invoker Invoker) bool { + _, found := invokerBlackList.Load(invoker.GetUrl().Key()) + return !found +} + +func SetInvokerUnhealthyStatus(invoker Invoker) { + invokerBlackList.Store(invoker.GetUrl().Key(), invoker) +} + +func RemoveInvokerUnhealthyStatus(invoker Invoker) { + invokerBlackList.Delete(invoker.GetUrl().Key()) +} + +func GetBlackListInvokers(blockSize int) []Invoker { + resultIvks := make([]Invoker, 0, 16) + invokerBlackList.Range(func(k, v interface{}) bool { + resultIvks = append(resultIvks, v.(Invoker)) + return true + }) + if blockSize > len(resultIvks) { + return resultIvks + } + return resultIvks[:blockSize] } diff --git a/registry/directory/directory.go b/registry/directory/directory.go index e6ae0f3bb9..d8ff9375e6 100644 --- a/registry/directory/directory.go +++ b/registry/directory/directory.go @@ -83,11 +83,13 @@ func NewRegistryDirectory(url *common.URL, registry registry.Registry) (cluster. dir.consumerURL = dir.getConsumerUrl(url.SubURL) + logger.Info("in NewRegistryDirectory ") if routerChain, err := chain.NewRouterChain(dir.consumerURL); err == nil { dir.BaseDirectory.SetRouterChain(routerChain) } else { logger.Warnf("fail to create router chain with url: %s, err is: %v", url.SubURL, err) } + logger.Info("here") dir.consumerConfigurationListener = newConsumerConfigurationListener(dir) From a707429cea86aa3401ca225d6040341a947e97bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=BF=97=E4=BF=A1?= Date: Wed, 9 Dec 2020 09:56:20 +0800 Subject: [PATCH 02/39] fix: delete unused comment --- cluster/cluster_impl/base_cluster_invoker.go | 2 -- registry/directory/directory.go | 2 -- 2 files changed, 4 deletions(-) diff --git a/cluster/cluster_impl/base_cluster_invoker.go b/cluster/cluster_impl/base_cluster_invoker.go index 891b189ba0..85ab4ceb16 100644 --- a/cluster/cluster_impl/base_cluster_invoker.go +++ b/cluster/cluster_impl/base_cluster_invoker.go @@ -138,7 +138,6 @@ func (invoker *baseClusterInvoker) doSelectInvoker(lb cluster.LoadBalance, invoc //judge to if the selectedInvoker is invoked and available if (!selectedInvoker.IsAvailable() && invoker.availablecheck) || isInvoked(selectedInvoker, invoked) { - // 拉黑当前 protocol.SetInvokerUnhealthyStatus(selectedInvoker) // do reselect @@ -148,7 +147,6 @@ func (invoker *baseClusterInvoker) doSelectInvoker(lb cluster.LoadBalance, invoc if !invoker.IsAvailable() { logger.Infof("the invoker of %s is not available, maybe some network error happened or the server is shutdown.", invoker.GetUrl().Ip) - // 拉黑reselect protocol.SetInvokerUnhealthyStatus(invoker) continue } diff --git a/registry/directory/directory.go b/registry/directory/directory.go index d8ff9375e6..e6ae0f3bb9 100644 --- a/registry/directory/directory.go +++ b/registry/directory/directory.go @@ -83,13 +83,11 @@ func NewRegistryDirectory(url *common.URL, registry registry.Registry) (cluster. dir.consumerURL = dir.getConsumerUrl(url.SubURL) - logger.Info("in NewRegistryDirectory ") if routerChain, err := chain.NewRouterChain(dir.consumerURL); err == nil { dir.BaseDirectory.SetRouterChain(routerChain) } else { logger.Warnf("fail to create router chain with url: %s, err is: %v", url.SubURL, err) } - logger.Info("here") dir.consumerConfigurationListener = newConsumerConfigurationListener(dir) From 353391f43792198f14893e1235573e855f5e1320 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=BF=97=E4=BF=A1?= Date: Wed, 9 Dec 2020 10:15:05 +0800 Subject: [PATCH 03/39] fmt file --- cluster/router/healthcheck/default_health_check.go | 3 +-- common/constant/key.go | 1 - registry/zookeeper/registry.go | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/cluster/router/healthcheck/default_health_check.go b/cluster/router/healthcheck/default_health_check.go index a59e58ff61..f1ae9c20a2 100644 --- a/cluster/router/healthcheck/default_health_check.go +++ b/cluster/router/healthcheck/default_health_check.go @@ -48,7 +48,7 @@ type DefaultHealthChecker struct { // IsHealthy evaluates the healthy state on the given Invoker based on the number of successive bad request // and the current active request func (c *DefaultHealthChecker) IsHealthy(invoker protocol.Invoker) bool { - if !protocol.GetInvokerHealthyStatus(invoker){ + if !protocol.GetInvokerHealthyStatus(invoker) { return false } @@ -96,7 +96,6 @@ func (c *DefaultHealthChecker) getCircuitBreakerSleepWindowTime(status *protocol return int64(sleepWindow) } - // GetRequestSuccessiveFailureThreshold return the requestSuccessiveFailureThreshold bound to this DefaultHealthChecker func (c *DefaultHealthChecker) GetRequestSuccessiveFailureThreshold() int32 { return c.requestSuccessiveFailureThreshold diff --git a/common/constant/key.go b/common/constant/key.go index b10d12d798..786c6ed016 100644 --- a/common/constant/key.go +++ b/common/constant/key.go @@ -90,7 +90,6 @@ const ( RETRY_TIMES_KEY = "retry.times" CYCLE_REPORT_KEY = "cycle.report" DEFAULT_BLACK_LIST_RECOVER_BLOCK = 10 - ) const ( diff --git a/registry/zookeeper/registry.go b/registry/zookeeper/registry.go index 76fc052b6f..fe492c2b12 100644 --- a/registry/zookeeper/registry.go +++ b/registry/zookeeper/registry.go @@ -212,7 +212,7 @@ func (r *zkRegistry) registerTempZookeeperNode(root string, node string) error { r.cltLock.Lock() defer r.cltLock.Unlock() - if r.client == nil{ + if r.client == nil { return perrors.WithStack(perrors.New("zk client already been closed")) } err = r.client.Create(root) From b3eff92eec8b1e431b492bbcf274b2a420dbb8d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=BF=97=E4=BF=A1?= Date: Fri, 11 Dec 2020 13:49:34 +0800 Subject: [PATCH 04/39] fix: add remove from blacklist procedure when unregistry --- protocol/rpc_status.go | 5 +++++ registry/directory/directory.go | 1 + 2 files changed, 6 insertions(+) diff --git a/protocol/rpc_status.go b/protocol/rpc_status.go index 7a915f4f5a..e0fc7134f1 100644 --- a/protocol/rpc_status.go +++ b/protocol/rpc_status.go @@ -213,3 +213,8 @@ func GetBlackListInvokers(blockSize int) []Invoker { } return resultIvks[:blockSize] } + +// RemoveUrlKeyUnhealthyStatus called when event of provider unregister, delete from black list +func RemoveUrlKeyUnhealthyStatus(key string) { + invokerBlackList.Delete(key) +} diff --git a/registry/directory/directory.go b/registry/directory/directory.go index e6ae0f3bb9..2c9de9ac5b 100644 --- a/registry/directory/directory.go +++ b/registry/directory/directory.go @@ -269,6 +269,7 @@ func (dir *RegistryDirectory) uncacheInvoker(url *common.URL) protocol.Invoker { func (dir *RegistryDirectory) uncacheInvokerWithKey(key string) protocol.Invoker { logger.Debugf("service will be deleted in cache invokers: invokers key is %s!", key) + protocol.RemoveUrlKeyUnhealthyStatus(key) if cacheInvoker, ok := dir.cacheInvokersMap.Load(key); ok { dir.cacheInvokersMap.Delete(key) return cacheInvoker.(protocol.Invoker) From 72e3dff4e0124995cb3f90467349a5080d3d9dd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=BF=97=E4=BF=A1?= Date: Fri, 11 Dec 2020 14:17:09 +0800 Subject: [PATCH 05/39] fix: change gost version to 1.10 --- config/config_loader_test.go | 2 +- go.mod | 2 +- go.sum | 3 +++ registry/consul/service_discovery.go | 6 +++--- registry/etcdv3/service_discovery.go | 6 +++--- registry/event/event_publishing_service_deiscovery_test.go | 2 +- registry/event/event_publishing_service_discovery.go | 2 +- registry/file/service_discovery.go | 2 +- registry/nacos/service_discovery.go | 6 +++--- registry/service_discovery.go | 2 +- .../servicediscovery/service_discovery_registry_test.go | 2 +- registry/zookeeper/service_discovery.go | 6 +++--- 12 files changed, 22 insertions(+), 19 deletions(-) diff --git a/config/config_loader_test.go b/config/config_loader_test.go index 9b253030ff..b6e6b69cb3 100644 --- a/config/config_loader_test.go +++ b/config/config_loader_test.go @@ -27,7 +27,7 @@ import ( import ( "github.com/Workiva/go-datastructures/slice/skip" gxset "github.com/dubbogo/gost/container/set" - gxpage "github.com/dubbogo/gost/page" + gxpage "github.com/dubbogo/gost/hash/page" "github.com/stretchr/testify/assert" "go.uber.org/atomic" ) diff --git a/go.mod b/go.mod index b1a37df9fb..5f954a3f89 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/coreos/etcd v3.3.25+incompatible github.com/creasty/defaults v1.5.1 github.com/dubbogo/go-zookeeper v1.0.2 - github.com/dubbogo/gost v1.9.2 + github.com/dubbogo/gost v1.10.0 github.com/elazarl/go-bindata-assetfs v1.0.0 // indirect github.com/emicklei/go-restful/v3 v3.0.0 github.com/frankban/quicktest v1.4.1 // indirect diff --git a/go.sum b/go.sum index 7c0426d966..a30f2bd5e5 100644 --- a/go.sum +++ b/go.sum @@ -215,6 +215,9 @@ github.com/dubbogo/go-zookeeper v1.0.2/go.mod h1:fn6n2CAEer3novYgk9ULLwAjuV8/g4D github.com/dubbogo/gost v1.9.0/go.mod h1:pPTjVyoJan3aPxBPNUX0ADkXjPibLo+/Ib0/fADXSG8= github.com/dubbogo/gost v1.9.2 h1:lTo5WETmqDKSW4d+Fr3Emiz1rKsVaQCPWRypJPAAfcw= github.com/dubbogo/gost v1.9.2/go.mod h1:QNM5RaeRdNWehUu8S0hUP5Qa8QUfGf6KH1JhqOVFvEI= +github.com/dubbogo/gost v1.10.0 h1:LGZlrNAICZzPXAXU/t3gwnV4gxW2CcXvbjfx28G5164= +github.com/dubbogo/gost v1.10.0/go.mod h1:+mQGS51XQEUWZP2JeGZTxJwipjRKtJO7Tr+FOg+72rI= +github.com/dubbogo/jsonparser v1.0.1/go.mod h1:tYAtpctvSP/tWw4MeelsowSPgXQRVHHWbqL6ynps8jU= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= diff --git a/registry/consul/service_discovery.go b/registry/consul/service_discovery.go index d8ab93f31e..79b10f51d4 100644 --- a/registry/consul/service_discovery.go +++ b/registry/consul/service_discovery.go @@ -27,7 +27,7 @@ import ( import ( "github.com/dubbogo/gost/container/set" - "github.com/dubbogo/gost/page" + "github.com/dubbogo/gost/hash/page" consul "github.com/hashicorp/consul/api" "github.com/hashicorp/consul/api/watch" perrors "github.com/pkg/errors" @@ -339,7 +339,7 @@ func (csd *consulServiceDiscovery) GetInstancesByPage(serviceName string, offset for i := offset; i < len(all) && i < offset+pageSize; i++ { res = append(res, all[i]) } - return gxpage.New(offset, pageSize, res, len(all)) + return gxpage.NewPage(offset, pageSize, res, len(all)) } func (csd *consulServiceDiscovery) GetHealthyInstancesByPage(serviceName string, offset int, pageSize int, healthy bool) gxpage.Pager { @@ -358,7 +358,7 @@ func (csd *consulServiceDiscovery) GetHealthyInstancesByPage(serviceName string, } i++ } - return gxpage.New(offset, pageSize, res, len(all)) + return gxpage.NewPage(offset, pageSize, res, len(all)) } func (csd *consulServiceDiscovery) GetRequestInstances(serviceNames []string, offset int, requestedSize int) map[string]gxpage.Pager { diff --git a/registry/etcdv3/service_discovery.go b/registry/etcdv3/service_discovery.go index e8d4aea9a4..3d0312973e 100644 --- a/registry/etcdv3/service_discovery.go +++ b/registry/etcdv3/service_discovery.go @@ -26,7 +26,7 @@ import ( import ( gxset "github.com/dubbogo/gost/container/set" - gxpage "github.com/dubbogo/gost/page" + gxpage "github.com/dubbogo/gost/hash/page" "github.com/hashicorp/vault/sdk/helper/jsonutil" perrors "github.com/pkg/errors" ) @@ -177,7 +177,7 @@ func (e *etcdV3ServiceDiscovery) GetInstancesByPage(serviceName string, offset i res = append(res, all[i]) } - return gxpage.New(offset, pageSize, res, len(all)) + return gxpage.NewPage(offset, pageSize, res, len(all)) } // GetHealthyInstancesByPage will return a page containing instances of ServiceInstance. @@ -199,7 +199,7 @@ func (e *etcdV3ServiceDiscovery) GetHealthyInstancesByPage(serviceName string, o } i++ } - return gxpage.New(offset, pageSize, res, len(all)) + return gxpage.NewPage(offset, pageSize, res, len(all)) } // Batch get all instances by the specified service names diff --git a/registry/event/event_publishing_service_deiscovery_test.go b/registry/event/event_publishing_service_deiscovery_test.go index 54752c03c0..504f7b5fae 100644 --- a/registry/event/event_publishing_service_deiscovery_test.go +++ b/registry/event/event_publishing_service_deiscovery_test.go @@ -24,7 +24,7 @@ import ( import ( gxset "github.com/dubbogo/gost/container/set" - gxpage "github.com/dubbogo/gost/page" + gxpage "github.com/dubbogo/gost/hash/page" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" ) diff --git a/registry/event/event_publishing_service_discovery.go b/registry/event/event_publishing_service_discovery.go index 3ee2f4a449..773eee6e83 100644 --- a/registry/event/event_publishing_service_discovery.go +++ b/registry/event/event_publishing_service_discovery.go @@ -19,7 +19,7 @@ package event import ( gxset "github.com/dubbogo/gost/container/set" - gxpage "github.com/dubbogo/gost/page" + gxpage "github.com/dubbogo/gost/hash/page" ) import ( diff --git a/registry/file/service_discovery.go b/registry/file/service_discovery.go index 254c12688f..c7d9c6539b 100644 --- a/registry/file/service_discovery.go +++ b/registry/file/service_discovery.go @@ -28,7 +28,7 @@ import ( import ( gxset "github.com/dubbogo/gost/container/set" - gxpage "github.com/dubbogo/gost/page" + gxpage "github.com/dubbogo/gost/hash/page" perrors "github.com/pkg/errors" ) diff --git a/registry/nacos/service_discovery.go b/registry/nacos/service_discovery.go index 0e5ad8e699..87523b0246 100644 --- a/registry/nacos/service_discovery.go +++ b/registry/nacos/service_discovery.go @@ -24,7 +24,7 @@ import ( import ( "github.com/dubbogo/gost/container/set" - "github.com/dubbogo/gost/page" + "github.com/dubbogo/gost/hash/page" "github.com/nacos-group/nacos-sdk-go/clients/naming_client" "github.com/nacos-group/nacos-sdk-go/model" "github.com/nacos-group/nacos-sdk-go/vo" @@ -174,7 +174,7 @@ func (n *nacosServiceDiscovery) GetInstancesByPage(serviceName string, offset in for i := offset; i < len(all) && i < offset+pageSize; i++ { res = append(res, all[i]) } - return gxpage.New(offset, pageSize, res, len(all)) + return gxpage.NewPage(offset, pageSize, res, len(all)) } // GetHealthyInstancesByPage will return the instance @@ -197,7 +197,7 @@ func (n *nacosServiceDiscovery) GetHealthyInstancesByPage(serviceName string, of } i++ } - return gxpage.New(offset, pageSize, res, len(all)) + return gxpage.NewPage(offset, pageSize, res, len(all)) } // GetRequestInstances will return the instances diff --git a/registry/service_discovery.go b/registry/service_discovery.go index cb7a3c0182..5ab7683515 100644 --- a/registry/service_discovery.go +++ b/registry/service_discovery.go @@ -23,7 +23,7 @@ import ( import ( gxset "github.com/dubbogo/gost/container/set" - gxpage "github.com/dubbogo/gost/page" + gxpage "github.com/dubbogo/gost/hash/page" ) const DefaultPageSize = 100 diff --git a/registry/servicediscovery/service_discovery_registry_test.go b/registry/servicediscovery/service_discovery_registry_test.go index ad6b73d3b4..2649e8c0f7 100644 --- a/registry/servicediscovery/service_discovery_registry_test.go +++ b/registry/servicediscovery/service_discovery_registry_test.go @@ -23,7 +23,7 @@ import ( import ( "github.com/dubbogo/gost/container/set" - "github.com/dubbogo/gost/page" + "github.com/dubbogo/gost/hash/page" "github.com/stretchr/testify/assert" ) import ( diff --git a/registry/zookeeper/service_discovery.go b/registry/zookeeper/service_discovery.go index 6d9582f33a..e5bbafd588 100644 --- a/registry/zookeeper/service_discovery.go +++ b/registry/zookeeper/service_discovery.go @@ -27,7 +27,7 @@ import ( import ( "github.com/dubbogo/gost/container/set" - "github.com/dubbogo/gost/page" + "github.com/dubbogo/gost/hash/page" perrors "github.com/pkg/errors" ) @@ -231,7 +231,7 @@ func (zksd *zookeeperServiceDiscovery) GetInstancesByPage(serviceName string, of for i := offset; i < len(all) && i < offset+pageSize; i++ { res = append(res, all[i]) } - return gxpage.New(offset, pageSize, res, len(all)) + return gxpage.NewPage(offset, pageSize, res, len(all)) } // GetHealthyInstancesByPage will return the instance @@ -254,7 +254,7 @@ func (zksd *zookeeperServiceDiscovery) GetHealthyInstancesByPage(serviceName str } i++ } - return gxpage.New(offset, pageSize, res, len(all)) + return gxpage.NewPage(offset, pageSize, res, len(all)) } // GetRequestInstances will return the instances From e958d6997807085cf48e1a4ce8422b44a2dbd4ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=BF=97=E4=BF=A1?= Date: Fri, 18 Dec 2020 16:57:12 +0800 Subject: [PATCH 06/39] fix: add connCheck and fix refresh logic --- cluster/cluster_impl/base_cluster_invoker.go | 48 ++--- cluster/router/conn_checker.go | 28 +++ cluster/router/conncheck/conn_check_route.go | 102 +++++++++++ .../router/conncheck/conn_check_route_test.go | 147 ++++++++++++++++ cluster/router/conncheck/conn_health_check.go | 45 +++++ .../conncheck/conn_health_check_test.go | 164 ++++++++++++++++++ cluster/router/conncheck/factory.go | 43 +++++ cluster/router/conncheck/factory_test.go | 74 ++++++++ .../healthcheck/default_health_check.go | 4 - common/constant/key.go | 6 +- common/extension/conn_checker.go | 40 +++++ go.mod | 2 +- go.sum | 2 + protocol/rpc_status.go | 35 +++- 14 files changed, 707 insertions(+), 33 deletions(-) create mode 100644 cluster/router/conn_checker.go create mode 100644 cluster/router/conncheck/conn_check_route.go create mode 100644 cluster/router/conncheck/conn_check_route_test.go create mode 100644 cluster/router/conncheck/conn_health_check.go create mode 100644 cluster/router/conncheck/conn_health_check_test.go create mode 100644 cluster/router/conncheck/factory.go create mode 100644 cluster/router/conncheck/factory_test.go create mode 100644 common/extension/conn_checker.go diff --git a/cluster/cluster_impl/base_cluster_invoker.go b/cluster/cluster_impl/base_cluster_invoker.go index 85ab4ceb16..a2d65291f4 100644 --- a/cluster/cluster_impl/base_cluster_invoker.go +++ b/cluster/cluster_impl/base_cluster_invoker.go @@ -124,7 +124,7 @@ func (invoker *baseClusterInvoker) doSelectInvoker(lb cluster.LoadBalance, invoc logger.Errorf("the invokers of %s is nil. ", invocation.Invoker().GetUrl().ServiceKey()) return nil } - refreshBlackList() + go protocol.TryRefreshBlackList() if len(invokers) == 1 { if invokers[0].IsAvailable() { return invokers[0] @@ -139,28 +139,28 @@ func (invoker *baseClusterInvoker) doSelectInvoker(lb cluster.LoadBalance, invoc //judge to if the selectedInvoker is invoked and available if (!selectedInvoker.IsAvailable() && invoker.availablecheck) || isInvoked(selectedInvoker, invoked) { protocol.SetInvokerUnhealthyStatus(selectedInvoker) - + otherInvokers := getOtherInvokers(invokers, selectedInvoker) // do reselect - var reslectInvokers []protocol.Invoker - - for _, invoker := range invokers { - if !invoker.IsAvailable() { + for i := 0; i < 3; i++ { + if len(otherInvokers) == 0 { + // no other ivk to reselect, return to fallback + logger.Errorf("all %d invokers is unavailable for %s.", len(invokers), selectedInvoker.GetUrl().String()) + return nil + } + reselectedInvoker := lb.Select(otherInvokers, invocation) + if isInvoked(reselectedInvoker, invoked) { + otherInvokers = getOtherInvokers(otherInvokers, reselectedInvoker) + continue + } + if !reselectedInvoker.IsAvailable() { logger.Infof("the invoker of %s is not available, maybe some network error happened or the server is shutdown.", invoker.GetUrl().Ip) - protocol.SetInvokerUnhealthyStatus(invoker) + protocol.SetInvokerUnhealthyStatus(reselectedInvoker) + otherInvokers = getOtherInvokers(otherInvokers, reselectedInvoker) continue } - - if !isInvoked(invoker, invoked) { - reslectInvokers = append(reslectInvokers, invoker) - } - } - - if len(reslectInvokers) > 0 { - selectedInvoker = lb.Select(reslectInvokers, invocation) - } else { - logger.Errorf("all %d invokers is unavailable for %s.", len(invokers), selectedInvoker.GetUrl().String()) - return nil + selectedInvoker = reselectedInvoker + break } } return selectedInvoker @@ -203,12 +203,12 @@ func getLoadBalance(invoker protocol.Invoker, invocation protocol.Invocation) cl return extension.GetLoadbalance(lb) } -func refreshBlackList() { - ivks := protocol.GetBlackListInvokers(constant.DEFAULT_BLACK_LIST_RECOVER_BLOCK) - logger.Debug("blackList len = ", len(ivks)) - for i, _ := range ivks { - if ivks[i].(protocol.Invoker).IsAvailable() { - protocol.RemoveInvokerUnhealthyStatus(ivks[i]) +func getOtherInvokers(invokers []protocol.Invoker, invoker protocol.Invoker) []protocol.Invoker { + otherInvokers := make([]protocol.Invoker, 0) + for _, i := range invokers { + if i != invoker { + otherInvokers = append(otherInvokers, i) } } + return otherInvokers } diff --git a/cluster/router/conn_checker.go b/cluster/router/conn_checker.go new file mode 100644 index 0000000000..fda0ef868b --- /dev/null +++ b/cluster/router/conn_checker.go @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package router + +import ( + "github.com/apache/dubbo-go/protocol" +) + +// ConnChecker is used to determine whether the invoker is healthy or not +type ConnChecker interface { + // IsConnHealthy evaluates the healthy state on the given Invoker + IsConnHealthy(invoker protocol.Invoker) bool +} diff --git a/cluster/router/conncheck/conn_check_route.go b/cluster/router/conncheck/conn_check_route.go new file mode 100644 index 0000000000..0826821b28 --- /dev/null +++ b/cluster/router/conncheck/conn_check_route.go @@ -0,0 +1,102 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package healthcheck + +import ( + "github.com/RoaringBitmap/roaring" +) + +import ( + "github.com/apache/dubbo-go/cluster/router" + "github.com/apache/dubbo-go/cluster/router/utils" + "github.com/apache/dubbo-go/common" + "github.com/apache/dubbo-go/common/constant" + "github.com/apache/dubbo-go/common/extension" + "github.com/apache/dubbo-go/common/logger" + "github.com/apache/dubbo-go/protocol" +) + +const ( + connHealthy = "conn-healthy" + name = "conn-check-router" +) + +// ConnCheckRouter provides a health-first routing mechanism through ConnChecker +type ConnCheckRouter struct { + url *common.URL + checker router.ConnChecker +} + +// NewConnCheckRouter construct an NewConnCheckRouter via url +func NewConnCheckRouter(url *common.URL) (router.PriorityRouter, error) { + r := &ConnCheckRouter{ + url: url, + } + checkerName := url.GetParam(constant.HEALTH_CHECKER, constant.DEFAULT_HEALTH_CHECKER) + r.checker = extension.GetConnChecker(checkerName, url) + return r, nil +} + +// Route gets a list of healthy invoker +func (r *ConnCheckRouter) Route(invokers *roaring.Bitmap, cache router.Cache, url *common.URL, invocation protocol.Invocation) *roaring.Bitmap { + addrPool := cache.FindAddrPool(r) + // Add healthy invoker to the list + healthyInvokers := utils.JoinIfNotEqual(addrPool[connHealthy], invokers) + // If all invokers are considered unhealthy, downgrade to all invoker + if healthyInvokers.IsEmpty() { + logger.Warnf(" Now all invokers are unhealthy, so downgraded to all! Service: [%s]", url.ServiceKey()) + return invokers + } + return healthyInvokers +} + +// Pool separates healthy invokers from others. +func (r *ConnCheckRouter) Pool(invokers []protocol.Invoker) (router.AddrPool, router.AddrMetadata) { + rb := make(router.AddrPool, 8) + rb[connHealthy] = roaring.NewBitmap() + for i, invoker := range invokers { + if r.checker.IsConnHealthy(invoker) { + rb[connHealthy].Add(uint32(i)) + } + } + return rb, nil +} + +// ShouldPool will always return true to make sure healthy check constantly. +func (r *ConnCheckRouter) ShouldPool() bool { + return true +} + +func (r *ConnCheckRouter) Name() string { + return name +} + +// Priority +func (r *ConnCheckRouter) Priority() int64 { + return 0 +} + +// URL Return URL in router +func (r *ConnCheckRouter) URL() *common.URL { + return r.url +} + +// ConnChecker returns the HealthChecker bound to this HealthCheckRouter +func (r *ConnCheckRouter) ConnChecker() router.ConnChecker { + return r.checker +} diff --git a/cluster/router/conncheck/conn_check_route_test.go b/cluster/router/conncheck/conn_check_route_test.go new file mode 100644 index 0000000000..4b9cacc17c --- /dev/null +++ b/cluster/router/conncheck/conn_check_route_test.go @@ -0,0 +1,147 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package healthcheck + +import ( + "fmt" + "math" + "testing" + "time" +) + +import ( + "github.com/stretchr/testify/assert" +) + +import ( + "github.com/apache/dubbo-go/cluster/router" + "github.com/apache/dubbo-go/cluster/router/chain" + "github.com/apache/dubbo-go/cluster/router/utils" + "github.com/apache/dubbo-go/common" + "github.com/apache/dubbo-go/common/constant" + "github.com/apache/dubbo-go/protocol" + "github.com/apache/dubbo-go/protocol/invocation" +) + +const ( + healthCheckRoute1010IP = "192.168.10.10" + healthCheckRoute1011IP = "192.168.10.11" + healthCheckRoute1012IP = "192.168.10.12" + healthCheckRouteMethodNameTest = "test" + healthCheck1001URL = "dubbo://192.168.10.1/com.ikurento.user.UserProvider" + healthCheckRouteUrlFormat = "dubbo://%s:20000/com.ikurento.user.UserProvider" +) + +func TestHealthCheckRouterRoute(t *testing.T) { + defer protocol.CleanAllStatus() + consumerURL, _ := common.NewURL(healthCheck1001URL) + consumerURL.SetParam(CONN_ROUTE_ENABLED_KEY, "true") + url1, _ := common.NewURL(fmt.Sprintf(healthCheckRouteUrlFormat, healthCheckRoute1010IP)) + url2, _ := common.NewURL(fmt.Sprintf(healthCheckRouteUrlFormat, healthCheckRoute1011IP)) + url3, _ := common.NewURL(fmt.Sprintf(healthCheckRouteUrlFormat, healthCheckRoute1012IP)) + hcr, _ := NewConnCheckRouter(consumerURL) + + var invokers []protocol.Invoker + invoker1 := NewMockInvoker(url1) + invoker2 := NewMockInvoker(url2) + invoker3 := NewMockInvoker(url3) + invokers = append(invokers, invoker1, invoker2, invoker3) + inv := invocation.NewRPCInvocation(healthCheckRouteMethodNameTest, nil, nil) + res := hcr.Route(utils.ToBitmap(invokers), setUpAddrCache(hcr.(*HealthCheckRouter), invokers), consumerURL, inv) + // now all invokers are healthy + assert.True(t, len(res.ToArray()) == len(invokers)) + + for i := 0; i < 10; i++ { + request(url1, healthCheckRouteMethodNameTest, 0, false, false) + } + res = hcr.Route(utils.ToBitmap(invokers), setUpAddrCache(hcr.(*HealthCheckRouter), invokers), consumerURL, inv) + // invokers1 is unhealthy now + assert.True(t, len(res.ToArray()) == 2 && !res.Contains(0)) + + for i := 0; i < 10; i++ { + request(url1, healthCheckRouteMethodNameTest, 0, false, false) + request(url2, healthCheckRouteMethodNameTest, 0, false, false) + } + + res = hcr.Route(utils.ToBitmap(invokers), setUpAddrCache(hcr.(*HealthCheckRouter), invokers), consumerURL, inv) + // only invokers3 is healthy now + assert.True(t, len(res.ToArray()) == 1 && !res.Contains(0) && !res.Contains(1)) + + for i := 0; i < 10; i++ { + request(url1, healthCheckRouteMethodNameTest, 0, false, false) + request(url2, healthCheckRouteMethodNameTest, 0, false, false) + request(url3, healthCheckRouteMethodNameTest, 0, false, false) + } + + res = hcr.Route(utils.ToBitmap(invokers), setUpAddrCache(hcr.(*HealthCheckRouter), invokers), consumerURL, inv) + // now all invokers are unhealthy, so downgraded to all + assert.True(t, len(res.ToArray()) == 3) + + // reset the invoker1 successive failed count, so invoker1 go to healthy + request(url1, healthCheckRouteMethodNameTest, 0, false, true) + res = hcr.Route(utils.ToBitmap(invokers), setUpAddrCache(hcr.(*HealthCheckRouter), invokers), consumerURL, inv) + assert.True(t, res.Contains(0)) + + for i := 0; i < 6; i++ { + request(url1, healthCheckRouteMethodNameTest, 0, false, false) + } + // now all invokers are unhealthy, so downgraded to all again + res = hcr.Route(utils.ToBitmap(invokers), setUpAddrCache(hcr.(*HealthCheckRouter), invokers), consumerURL, inv) + assert.True(t, len(res.ToArray()) == 3) + time.Sleep(time.Second * 2) + // invoker1 go to healthy again after 2s + res = hcr.Route(utils.ToBitmap(invokers), setUpAddrCache(hcr.(*HealthCheckRouter), invokers), consumerURL, inv) + assert.True(t, res.Contains(0)) + +} + +func TestNewHealthCheckRouter(t *testing.T) { + defer protocol.CleanAllStatus() + url, _ := common.NewURL(fmt.Sprintf(healthCheckDubboUrlFormat, healthCheckDubbo1010IP)) + hcr, _ := NewHealthCheckRouter(url) + h := hcr.(*HealthCheckRouter) + assert.Nil(t, h.checker) + + url.SetParam(HEALTH_ROUTE_ENABLED_KEY, "true") + hcr, _ = NewHealthCheckRouter(url) + h = hcr.(*HealthCheckRouter) + assert.NotNil(t, h.checker) + + dhc := h.checker.(*DefaultHealthChecker) + assert.Equal(t, dhc.outStandingRequestConutLimit, int32(math.MaxInt32)) + assert.Equal(t, dhc.requestSuccessiveFailureThreshold, int32(constant.DEFAULT_SUCCESSIVE_FAILED_THRESHOLD)) + assert.Equal(t, dhc.circuitTrippedTimeoutFactor, int32(constant.DEFAULT_CIRCUIT_TRIPPED_TIMEOUT_FACTOR)) + + url.SetParam(constant.CIRCUIT_TRIPPED_TIMEOUT_FACTOR_KEY, "500") + url.SetParam(constant.SUCCESSIVE_FAILED_REQUEST_THRESHOLD_KEY, "10") + url.SetParam(constant.OUTSTANDING_REQUEST_COUNT_LIMIT_KEY, "1000") + hcr, _ = NewHealthCheckRouter(url) + h = hcr.(*HealthCheckRouter) + dhc = h.checker.(*DefaultHealthChecker) + assert.Equal(t, dhc.outStandingRequestConutLimit, int32(1000)) + assert.Equal(t, dhc.requestSuccessiveFailureThreshold, int32(10)) + assert.Equal(t, dhc.circuitTrippedTimeoutFactor, int32(500)) +} + +func setUpAddrCache(r router.Poolable, addrs []protocol.Invoker) router.Cache { + pool, info := r.Pool(addrs) + cache := chain.BuildCache(addrs) + cache.SetAddrMeta(r.Name(), info) + cache.SetAddrPool(r.Name(), pool) + return cache +} diff --git a/cluster/router/conncheck/conn_health_check.go b/cluster/router/conncheck/conn_health_check.go new file mode 100644 index 0000000000..54d39f931b --- /dev/null +++ b/cluster/router/conncheck/conn_health_check.go @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package healthcheck + +import ( + "github.com/apache/dubbo-go/cluster/router" + "github.com/apache/dubbo-go/common" + "github.com/apache/dubbo-go/common/constant" + "github.com/apache/dubbo-go/common/extension" + "github.com/apache/dubbo-go/protocol" +) + +func init() { + extension.SetConnChecker(constant.DEFAULT_CONN_CHECKER, NewDefaultConnChecker) +} + +// DefaultConnChecker is the default implementation of ConnChecker, which determines the health status of invoker conn +type DefaultConnChecker struct { +} + +// IsConnHealthy evaluates the healthy state on the given Invoker based on the number of successive bad request +// and the current active request +func (c *DefaultConnChecker) IsConnHealthy(invoker protocol.Invoker) bool { + return protocol.GetInvokerHealthyStatus(invoker) +} + +// NewDefaultConnChecker constructs a new DefaultConnChecker based on the url +func NewDefaultConnChecker(url *common.URL) router.ConnChecker { + return &DefaultConnChecker{} +} diff --git a/cluster/router/conncheck/conn_health_check_test.go b/cluster/router/conncheck/conn_health_check_test.go new file mode 100644 index 0000000000..39827c5f05 --- /dev/null +++ b/cluster/router/conncheck/conn_health_check_test.go @@ -0,0 +1,164 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package healthcheck + +import ( + "fmt" + "math" + "testing" +) + +import ( + "github.com/stretchr/testify/assert" +) + +import ( + "github.com/apache/dubbo-go/common" + "github.com/apache/dubbo-go/common/constant" + "github.com/apache/dubbo-go/protocol" +) + +const ( + healthCheckDubbo1010IP = "192.168.10.10" + healthCheckDubbo1011IP = "192.168.10.11" + healthCheckMethodTest = "test" + healthCheckDubboUrlFormat = "dubbo://%s:20000/com.ikurento.user.UserProvider" +) + +func TestDefaultHealthCheckerIsHealthy(t *testing.T) { + defer protocol.CleanAllStatus() + url, _ := common.NewURL(fmt.Sprintf(healthCheckDubboUrlFormat, healthCheckDubbo1010IP)) + hc := NewDefaultHealthChecker(url).(*DefaultHealthChecker) + invoker := NewMockInvoker(url) + healthy := hc.IsHealthy(invoker) + assert.True(t, healthy) + + url.SetParam(constant.OUTSTANDING_REQUEST_COUNT_LIMIT_KEY, "10") + url.SetParam(constant.SUCCESSIVE_FAILED_REQUEST_THRESHOLD_KEY, "100") + // fake the outgoing request + for i := 0; i < 11; i++ { + request(url, healthCheckMethodTest, 0, true, false) + } + hc = NewDefaultHealthChecker(url).(*DefaultHealthChecker) + healthy = hc.IsHealthy(invoker) + // the outgoing request is more than OUTSTANDING_REQUEST_COUNT_LIMIT, go to unhealthy + assert.False(t, hc.IsHealthy(invoker)) + + // successive failed count is more than constant.SUCCESSIVE_FAILED_REQUEST_THRESHOLD_KEY, go to unhealthy + for i := 0; i < 11; i++ { + request(url, healthCheckMethodTest, 0, false, false) + } + url.SetParam(constant.SUCCESSIVE_FAILED_REQUEST_THRESHOLD_KEY, "10") + url.SetParam(constant.OUTSTANDING_REQUEST_COUNT_LIMIT_KEY, "1000") + hc = NewDefaultHealthChecker(url).(*DefaultHealthChecker) + healthy = hc.IsHealthy(invoker) + assert.False(t, hc.IsHealthy(invoker)) + + // reset successive failed count and go to healthy + request(url, healthCheckMethodTest, 0, false, true) + healthy = hc.IsHealthy(invoker) + assert.True(t, hc.IsHealthy(invoker)) +} + +func TestDefaultHealthCheckerGetCircuitBreakerSleepWindowTime(t *testing.T) { + defer protocol.CleanAllStatus() + url, _ := common.NewURL(fmt.Sprintf(healthCheckDubboUrlFormat, healthCheckDubbo1010IP)) + defaultHc := NewDefaultHealthChecker(url).(*DefaultHealthChecker) + // Increase the number of failed requests + for i := 0; i < 100; i++ { + request(url, healthCheckMethodTest, 1, false, false) + } + sleepWindowTime := defaultHc.getCircuitBreakerSleepWindowTime(protocol.GetURLStatus(url)) + assert.True(t, sleepWindowTime == constant.MAX_CIRCUIT_TRIPPED_TIMEOUT_IN_MS) + + // Adjust the threshold size to 1000 + url.SetParam(constant.SUCCESSIVE_FAILED_REQUEST_THRESHOLD_KEY, "1000") + sleepWindowTime = NewDefaultHealthChecker(url).(*DefaultHealthChecker).getCircuitBreakerSleepWindowTime(protocol.GetURLStatus(url)) + assert.True(t, sleepWindowTime == 0) + + url1, _ := common.NewURL(fmt.Sprintf(healthCheckDubboUrlFormat, healthCheckDubbo1011IP)) + sleepWindowTime = defaultHc.getCircuitBreakerSleepWindowTime(protocol.GetURLStatus(url1)) + assert.True(t, sleepWindowTime == 0) + request(url1, healthCheckMethodTest, 1, false, false) + request(url1, healthCheckMethodTest, 1, false, false) + request(url1, healthCheckMethodTest, 1, false, false) + request(url1, healthCheckMethodTest, 1, false, false) + request(url1, healthCheckMethodTest, 1, false, false) + request(url1, healthCheckMethodTest, 1, false, false) + sleepWindowTime = defaultHc.getCircuitBreakerSleepWindowTime(protocol.GetURLStatus(url1)) + assert.True(t, sleepWindowTime > 0 && sleepWindowTime < constant.MAX_CIRCUIT_TRIPPED_TIMEOUT_IN_MS) +} + +func TestDefaultHealthCheckerGetCircuitBreakerTimeout(t *testing.T) { + defer protocol.CleanAllStatus() + url, _ := common.NewURL(fmt.Sprintf(healthCheckDubboUrlFormat, healthCheckDubbo1010IP)) + defaultHc := NewDefaultHealthChecker(url).(*DefaultHealthChecker) + timeout := defaultHc.getCircuitBreakerTimeout(protocol.GetURLStatus(url)) + assert.True(t, timeout == 0) + url1, _ := common.NewURL(fmt.Sprintf(healthCheckDubboUrlFormat, healthCheckDubbo1011IP)) + request(url1, healthCheckMethodTest, 1, false, false) + request(url1, healthCheckMethodTest, 1, false, false) + request(url1, healthCheckMethodTest, 1, false, false) + request(url1, healthCheckMethodTest, 1, false, false) + request(url1, healthCheckMethodTest, 1, false, false) + request(url1, healthCheckMethodTest, 1, false, false) + timeout = defaultHc.getCircuitBreakerTimeout(protocol.GetURLStatus(url1)) + // timeout must after the current time + assert.True(t, timeout > protocol.CurrentTimeMillis()) + +} + +func TestDefaultHealthCheckerIsCircuitBreakerTripped(t *testing.T) { + defer protocol.CleanAllStatus() + url, _ := common.NewURL(fmt.Sprintf(healthCheckDubboUrlFormat, healthCheckDubbo1010IP)) + defaultHc := NewDefaultHealthChecker(url).(*DefaultHealthChecker) + status := protocol.GetURLStatus(url) + tripped := defaultHc.isCircuitBreakerTripped(status) + assert.False(t, tripped) + // Increase the number of failed requests + for i := 0; i < 100; i++ { + request(url, healthCheckMethodTest, 1, false, false) + } + tripped = defaultHc.isCircuitBreakerTripped(protocol.GetURLStatus(url)) + assert.True(t, tripped) + +} + +func TestNewDefaultHealthChecker(t *testing.T) { + defer protocol.CleanAllStatus() + url, _ := common.NewURL(fmt.Sprintf(healthCheckDubboUrlFormat, healthCheckDubbo1010IP)) + defaultHc := NewDefaultHealthChecker(url).(*DefaultHealthChecker) + assert.NotNil(t, defaultHc) + assert.Equal(t, defaultHc.outStandingRequestConutLimit, int32(math.MaxInt32)) + assert.Equal(t, defaultHc.requestSuccessiveFailureThreshold, int32(constant.DEFAULT_SUCCESSIVE_FAILED_REQUEST_MAX_DIFF)) + + url1, _ := common.NewURL(fmt.Sprintf(healthCheckDubboUrlFormat, healthCheckDubbo1010IP)) + url1.SetParam(constant.OUTSTANDING_REQUEST_COUNT_LIMIT_KEY, "10") + url1.SetParam(constant.SUCCESSIVE_FAILED_REQUEST_THRESHOLD_KEY, "10") + nondefaultHc := NewDefaultHealthChecker(url1).(*DefaultHealthChecker) + assert.NotNil(t, nondefaultHc) + assert.Equal(t, nondefaultHc.outStandingRequestConutLimit, int32(10)) + assert.Equal(t, nondefaultHc.requestSuccessiveFailureThreshold, int32(10)) +} + +func request(url *common.URL, method string, elapsed int64, active, succeeded bool) { + protocol.BeginCount(url, method) + if !active { + protocol.EndCount(url, method, elapsed, succeeded) + } +} diff --git a/cluster/router/conncheck/factory.go b/cluster/router/conncheck/factory.go new file mode 100644 index 0000000000..05d6a3815e --- /dev/null +++ b/cluster/router/conncheck/factory.go @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package healthcheck + +import ( + "github.com/apache/dubbo-go/cluster/router" + "github.com/apache/dubbo-go/common" + "github.com/apache/dubbo-go/common/constant" + "github.com/apache/dubbo-go/common/extension" +) + +func init() { + extension.SetRouterFactory(constant.ConnCheckRouterName, newConnCheckRouteFactory) +} + +// ConnCheckRouteFactory +type ConnCheckRouteFactory struct { +} + +// newHealthCheckRouteFactory construct a new HealthCheckRouteFactory +func newConnCheckRouteFactory() router.PriorityRouterFactory { + return &ConnCheckRouteFactory{} +} + +// NewPriorityRouter construct a new NewHealthCheckRouter via url +func (f *ConnCheckRouteFactory) NewPriorityRouter(url *common.URL) (router.PriorityRouter, error) { + return NewConnCheckRouter(url) +} diff --git a/cluster/router/conncheck/factory_test.go b/cluster/router/conncheck/factory_test.go new file mode 100644 index 0000000000..9e1870ae98 --- /dev/null +++ b/cluster/router/conncheck/factory_test.go @@ -0,0 +1,74 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package healthcheck + +import ( + "context" + "testing" +) + +import ( + "github.com/stretchr/testify/assert" +) + +import ( + "github.com/apache/dubbo-go/common" + "github.com/apache/dubbo-go/protocol" +) + +// nolint +type MockInvoker struct { + url *common.URL +} + +// nolint +func NewMockInvoker(url *common.URL) *MockInvoker { + return &MockInvoker{ + url: url, + } +} + +// nolint +func (bi *MockInvoker) GetUrl() *common.URL { + return bi.url +} + +// nolint +func (bi *MockInvoker) IsAvailable() bool { + return true +} + +// nolint +func (bi *MockInvoker) IsDestroyed() bool { + return true +} + +// nolint +func (bi *MockInvoker) Invoke(_ context.Context, _ protocol.Invocation) protocol.Result { + return nil +} + +// nolint +func (bi *MockInvoker) Destroy() { +} + +// nolint +func TestHealthCheckRouteFactory(t *testing.T) { + factory := newConnCheckRouteFactory() + assert.NotNil(t, factory) +} diff --git a/cluster/router/healthcheck/default_health_check.go b/cluster/router/healthcheck/default_health_check.go index f1ae9c20a2..eb15e6f642 100644 --- a/cluster/router/healthcheck/default_health_check.go +++ b/cluster/router/healthcheck/default_health_check.go @@ -48,10 +48,6 @@ type DefaultHealthChecker struct { // IsHealthy evaluates the healthy state on the given Invoker based on the number of successive bad request // and the current active request func (c *DefaultHealthChecker) IsHealthy(invoker protocol.Invoker) bool { - if !protocol.GetInvokerHealthyStatus(invoker) { - return false - } - urlStatus := protocol.GetURLStatus(invoker.GetUrl()) if c.isCircuitBreakerTripped(urlStatus) || urlStatus.GetActive() > c.GetOutStandingRequestCountLimit() { logger.Debugf("Invoker [%s] is currently in circuitbreaker tripped state", invoker.GetUrl().Key()) diff --git a/common/constant/key.go b/common/constant/key.go index 786c6ed016..5dedbc2c21 100644 --- a/common/constant/key.go +++ b/common/constant/key.go @@ -89,7 +89,7 @@ const ( RETRY_PERIOD_KEY = "retry.period" RETRY_TIMES_KEY = "retry.times" CYCLE_REPORT_KEY = "cycle.report" - DEFAULT_BLACK_LIST_RECOVER_BLOCK = 10 + DEFAULT_BLACK_LIST_RECOVER_BLOCK = 16 ) const ( @@ -211,6 +211,8 @@ const ( ListenableRouterName = "listenable" // HealthCheckRouterName Specify the name of HealthCheckRouter HealthCheckRouterName = "health_check" + // ConnCheckRouterName Specify the name of ConnCheckRouter + ConnCheckRouterName = "conn_check" // TagRouterName Specify the name of TagRouter TagRouterName = "tag" // TagRouterRuleSuffix Specify tag router suffix @@ -296,6 +298,8 @@ const ( HEALTH_CHECKER = "health.checker" // The name of the default implementation of HealthChecker DEFAULT_HEALTH_CHECKER = "default" + // The name of the default implementation of C + DEFAULT_CONN_CHECKER = "default" // The key of oustanding-request-limit OUTSTANDING_REQUEST_COUNT_LIMIT_KEY = "outstanding.request.limit" // The key of successive-failed-request's threshold diff --git a/common/extension/conn_checker.go b/common/extension/conn_checker.go new file mode 100644 index 0000000000..99add91f80 --- /dev/null +++ b/common/extension/conn_checker.go @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package extension + +import ( + "github.com/apache/dubbo-go/cluster/router" + "github.com/apache/dubbo-go/common" +) + +var ( + connCheckers = make(map[string]func(url *common.URL) router.ConnChecker) +) + +// SetHealthChecker sets the HealthChecker with @name +func SetConnChecker(name string, fcn func(_ *common.URL) router.ConnChecker) { + connCheckers[name] = fcn +} + +// GetHealthChecker gets the HealthChecker with @name +func GetConnChecker(name string, url *common.URL) router.ConnChecker { + if connCheckers[name] == nil { + panic("connCheckers for " + name + " is not existing, make sure you have import the package.") + } + return connCheckers[name](url) +} diff --git a/go.mod b/go.mod index 5f954a3f89..282877bb5d 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/coreos/etcd v3.3.25+incompatible github.com/creasty/defaults v1.5.1 github.com/dubbogo/go-zookeeper v1.0.2 - github.com/dubbogo/gost v1.10.0 + github.com/dubbogo/gost v1.10.1 github.com/elazarl/go-bindata-assetfs v1.0.0 // indirect github.com/emicklei/go-restful/v3 v3.0.0 github.com/frankban/quicktest v1.4.1 // indirect diff --git a/go.sum b/go.sum index a30f2bd5e5..ba6e62fcbb 100644 --- a/go.sum +++ b/go.sum @@ -217,6 +217,8 @@ github.com/dubbogo/gost v1.9.2 h1:lTo5WETmqDKSW4d+Fr3Emiz1rKsVaQCPWRypJPAAfcw= github.com/dubbogo/gost v1.9.2/go.mod h1:QNM5RaeRdNWehUu8S0hUP5Qa8QUfGf6KH1JhqOVFvEI= github.com/dubbogo/gost v1.10.0 h1:LGZlrNAICZzPXAXU/t3gwnV4gxW2CcXvbjfx28G5164= github.com/dubbogo/gost v1.10.0/go.mod h1:+mQGS51XQEUWZP2JeGZTxJwipjRKtJO7Tr+FOg+72rI= +github.com/dubbogo/gost v1.10.1 h1:39kF9Cd5JOiMpmwG6dX1/aLWNFqFv9gHp8HrhzMmjLY= +github.com/dubbogo/gost v1.10.1/go.mod h1:+mQGS51XQEUWZP2JeGZTxJwipjRKtJO7Tr+FOg+72rI= github.com/dubbogo/jsonparser v1.0.1/go.mod h1:tYAtpctvSP/tWw4MeelsowSPgXQRVHHWbqL6ynps8jU= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= diff --git a/protocol/rpc_status.go b/protocol/rpc_status.go index e0fc7134f1..2e2aecffe7 100644 --- a/protocol/rpc_status.go +++ b/protocol/rpc_status.go @@ -18,6 +18,8 @@ package protocol import ( + "fmt" + "github.com/apache/dubbo-go/common/constant" "sync" "sync/atomic" "time" @@ -28,9 +30,10 @@ import ( ) var ( - methodStatistics sync.Map // url -> { methodName : RPCStatus} - serviceStatistic sync.Map // url -> RPCStatus - invokerBlackList sync.Map // store unhealthy url blackList + methodStatistics sync.Map // url -> { methodName : RPCStatus} + serviceStatistic sync.Map // url -> RPCStatus + invokerBlackList sync.Map // store unhealthy url blackList + blackListRefreshing int32 // store if the refresing method is processing ) // RPCStatus is URL statistics. @@ -218,3 +221,29 @@ func GetBlackListInvokers(blockSize int) []Invoker { func RemoveUrlKeyUnhealthyStatus(key string) { invokerBlackList.Delete(key) } + +func TryRefreshBlackList() { + if atomic.CompareAndSwapInt32(&blackListRefreshing, 0, 1) { + wg := sync.WaitGroup{} + defer func() { + atomic.CompareAndSwapInt32(&blackListRefreshing, 1, 0) + }() + + ivks := GetBlackListInvokers(constant.DEFAULT_BLACK_LIST_RECOVER_BLOCK) + fmt.Println("blackList len = ", len(ivks)) + + for i := 0; i < 3; i++ { + wg.Add(1) + go func(ivks []Invoker, i int) { + for j, _ := range ivks { + if j%3-i == 0 { + if ivks[j].(Invoker).IsAvailable() { + RemoveInvokerUnhealthyStatus(ivks[i]) + } + } + } + }(ivks, i) + } + wg.Wait() + } +} From f84b8fc4626f93aaefe1274ebfe30580c08bf030 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=BF=97=E4=BF=A1?= Date: Wed, 23 Dec 2020 13:51:37 +0800 Subject: [PATCH 07/39] fix: use logger --- protocol/rpc_status.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/protocol/rpc_status.go b/protocol/rpc_status.go index 2e2aecffe7..d4988cd938 100644 --- a/protocol/rpc_status.go +++ b/protocol/rpc_status.go @@ -18,8 +18,8 @@ package protocol import ( - "fmt" "github.com/apache/dubbo-go/common/constant" + "github.com/apache/dubbo-go/common/logger" "sync" "sync/atomic" "time" @@ -230,7 +230,7 @@ func TryRefreshBlackList() { }() ivks := GetBlackListInvokers(constant.DEFAULT_BLACK_LIST_RECOVER_BLOCK) - fmt.Println("blackList len = ", len(ivks)) + logger.Debug("blackList len = ", len(ivks)) for i := 0; i < 3; i++ { wg.Add(1) From f7073cf6d5f7bb66fa607db0093e5393205cbeb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=BF=97=E4=BF=A1?= Date: Wed, 23 Dec 2020 14:01:30 +0800 Subject: [PATCH 08/39] fix: back to 1.9.5 gost --- config/config_loader_test.go | 2 +- go.mod | 2 +- go.sum | 2 ++ registry/consul/service_discovery.go | 6 +++--- registry/etcdv3/service_discovery.go | 6 +++--- registry/event/event_publishing_service_deiscovery_test.go | 2 +- registry/event/event_publishing_service_discovery.go | 2 +- registry/file/service_discovery.go | 2 +- registry/nacos/service_discovery.go | 6 +++--- registry/service_discovery.go | 2 +- .../servicediscovery/service_discovery_registry_test.go | 2 +- registry/zookeeper/service_discovery.go | 6 +++--- 12 files changed, 21 insertions(+), 19 deletions(-) diff --git a/config/config_loader_test.go b/config/config_loader_test.go index b6e6b69cb3..9b253030ff 100644 --- a/config/config_loader_test.go +++ b/config/config_loader_test.go @@ -27,7 +27,7 @@ import ( import ( "github.com/Workiva/go-datastructures/slice/skip" gxset "github.com/dubbogo/gost/container/set" - gxpage "github.com/dubbogo/gost/hash/page" + gxpage "github.com/dubbogo/gost/page" "github.com/stretchr/testify/assert" "go.uber.org/atomic" ) diff --git a/go.mod b/go.mod index 282877bb5d..a24bbde535 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/coreos/etcd v3.3.25+incompatible github.com/creasty/defaults v1.5.1 github.com/dubbogo/go-zookeeper v1.0.2 - github.com/dubbogo/gost v1.10.1 + github.com/dubbogo/gost v1.9.5 github.com/elazarl/go-bindata-assetfs v1.0.0 // indirect github.com/emicklei/go-restful/v3 v3.0.0 github.com/frankban/quicktest v1.4.1 // indirect diff --git a/go.sum b/go.sum index ba6e62fcbb..20acd4c899 100644 --- a/go.sum +++ b/go.sum @@ -215,6 +215,8 @@ github.com/dubbogo/go-zookeeper v1.0.2/go.mod h1:fn6n2CAEer3novYgk9ULLwAjuV8/g4D github.com/dubbogo/gost v1.9.0/go.mod h1:pPTjVyoJan3aPxBPNUX0ADkXjPibLo+/Ib0/fADXSG8= github.com/dubbogo/gost v1.9.2 h1:lTo5WETmqDKSW4d+Fr3Emiz1rKsVaQCPWRypJPAAfcw= github.com/dubbogo/gost v1.9.2/go.mod h1:QNM5RaeRdNWehUu8S0hUP5Qa8QUfGf6KH1JhqOVFvEI= +github.com/dubbogo/gost v1.9.5 h1:UeG4y0O55lR3dzgdmCm/7bMWvpKrlpR7fsfKjrcXq/g= +github.com/dubbogo/gost v1.9.5/go.mod h1:QNM5RaeRdNWehUu8S0hUP5Qa8QUfGf6KH1JhqOVFvEI= github.com/dubbogo/gost v1.10.0 h1:LGZlrNAICZzPXAXU/t3gwnV4gxW2CcXvbjfx28G5164= github.com/dubbogo/gost v1.10.0/go.mod h1:+mQGS51XQEUWZP2JeGZTxJwipjRKtJO7Tr+FOg+72rI= github.com/dubbogo/gost v1.10.1 h1:39kF9Cd5JOiMpmwG6dX1/aLWNFqFv9gHp8HrhzMmjLY= diff --git a/registry/consul/service_discovery.go b/registry/consul/service_discovery.go index 79b10f51d4..d8ab93f31e 100644 --- a/registry/consul/service_discovery.go +++ b/registry/consul/service_discovery.go @@ -27,7 +27,7 @@ import ( import ( "github.com/dubbogo/gost/container/set" - "github.com/dubbogo/gost/hash/page" + "github.com/dubbogo/gost/page" consul "github.com/hashicorp/consul/api" "github.com/hashicorp/consul/api/watch" perrors "github.com/pkg/errors" @@ -339,7 +339,7 @@ func (csd *consulServiceDiscovery) GetInstancesByPage(serviceName string, offset for i := offset; i < len(all) && i < offset+pageSize; i++ { res = append(res, all[i]) } - return gxpage.NewPage(offset, pageSize, res, len(all)) + return gxpage.New(offset, pageSize, res, len(all)) } func (csd *consulServiceDiscovery) GetHealthyInstancesByPage(serviceName string, offset int, pageSize int, healthy bool) gxpage.Pager { @@ -358,7 +358,7 @@ func (csd *consulServiceDiscovery) GetHealthyInstancesByPage(serviceName string, } i++ } - return gxpage.NewPage(offset, pageSize, res, len(all)) + return gxpage.New(offset, pageSize, res, len(all)) } func (csd *consulServiceDiscovery) GetRequestInstances(serviceNames []string, offset int, requestedSize int) map[string]gxpage.Pager { diff --git a/registry/etcdv3/service_discovery.go b/registry/etcdv3/service_discovery.go index 3d0312973e..e8d4aea9a4 100644 --- a/registry/etcdv3/service_discovery.go +++ b/registry/etcdv3/service_discovery.go @@ -26,7 +26,7 @@ import ( import ( gxset "github.com/dubbogo/gost/container/set" - gxpage "github.com/dubbogo/gost/hash/page" + gxpage "github.com/dubbogo/gost/page" "github.com/hashicorp/vault/sdk/helper/jsonutil" perrors "github.com/pkg/errors" ) @@ -177,7 +177,7 @@ func (e *etcdV3ServiceDiscovery) GetInstancesByPage(serviceName string, offset i res = append(res, all[i]) } - return gxpage.NewPage(offset, pageSize, res, len(all)) + return gxpage.New(offset, pageSize, res, len(all)) } // GetHealthyInstancesByPage will return a page containing instances of ServiceInstance. @@ -199,7 +199,7 @@ func (e *etcdV3ServiceDiscovery) GetHealthyInstancesByPage(serviceName string, o } i++ } - return gxpage.NewPage(offset, pageSize, res, len(all)) + return gxpage.New(offset, pageSize, res, len(all)) } // Batch get all instances by the specified service names diff --git a/registry/event/event_publishing_service_deiscovery_test.go b/registry/event/event_publishing_service_deiscovery_test.go index 504f7b5fae..54752c03c0 100644 --- a/registry/event/event_publishing_service_deiscovery_test.go +++ b/registry/event/event_publishing_service_deiscovery_test.go @@ -24,7 +24,7 @@ import ( import ( gxset "github.com/dubbogo/gost/container/set" - gxpage "github.com/dubbogo/gost/hash/page" + gxpage "github.com/dubbogo/gost/page" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" ) diff --git a/registry/event/event_publishing_service_discovery.go b/registry/event/event_publishing_service_discovery.go index 773eee6e83..3ee2f4a449 100644 --- a/registry/event/event_publishing_service_discovery.go +++ b/registry/event/event_publishing_service_discovery.go @@ -19,7 +19,7 @@ package event import ( gxset "github.com/dubbogo/gost/container/set" - gxpage "github.com/dubbogo/gost/hash/page" + gxpage "github.com/dubbogo/gost/page" ) import ( diff --git a/registry/file/service_discovery.go b/registry/file/service_discovery.go index c7d9c6539b..254c12688f 100644 --- a/registry/file/service_discovery.go +++ b/registry/file/service_discovery.go @@ -28,7 +28,7 @@ import ( import ( gxset "github.com/dubbogo/gost/container/set" - gxpage "github.com/dubbogo/gost/hash/page" + gxpage "github.com/dubbogo/gost/page" perrors "github.com/pkg/errors" ) diff --git a/registry/nacos/service_discovery.go b/registry/nacos/service_discovery.go index 87523b0246..0e5ad8e699 100644 --- a/registry/nacos/service_discovery.go +++ b/registry/nacos/service_discovery.go @@ -24,7 +24,7 @@ import ( import ( "github.com/dubbogo/gost/container/set" - "github.com/dubbogo/gost/hash/page" + "github.com/dubbogo/gost/page" "github.com/nacos-group/nacos-sdk-go/clients/naming_client" "github.com/nacos-group/nacos-sdk-go/model" "github.com/nacos-group/nacos-sdk-go/vo" @@ -174,7 +174,7 @@ func (n *nacosServiceDiscovery) GetInstancesByPage(serviceName string, offset in for i := offset; i < len(all) && i < offset+pageSize; i++ { res = append(res, all[i]) } - return gxpage.NewPage(offset, pageSize, res, len(all)) + return gxpage.New(offset, pageSize, res, len(all)) } // GetHealthyInstancesByPage will return the instance @@ -197,7 +197,7 @@ func (n *nacosServiceDiscovery) GetHealthyInstancesByPage(serviceName string, of } i++ } - return gxpage.NewPage(offset, pageSize, res, len(all)) + return gxpage.New(offset, pageSize, res, len(all)) } // GetRequestInstances will return the instances diff --git a/registry/service_discovery.go b/registry/service_discovery.go index 5ab7683515..cb7a3c0182 100644 --- a/registry/service_discovery.go +++ b/registry/service_discovery.go @@ -23,7 +23,7 @@ import ( import ( gxset "github.com/dubbogo/gost/container/set" - gxpage "github.com/dubbogo/gost/hash/page" + gxpage "github.com/dubbogo/gost/page" ) const DefaultPageSize = 100 diff --git a/registry/servicediscovery/service_discovery_registry_test.go b/registry/servicediscovery/service_discovery_registry_test.go index 2649e8c0f7..ad6b73d3b4 100644 --- a/registry/servicediscovery/service_discovery_registry_test.go +++ b/registry/servicediscovery/service_discovery_registry_test.go @@ -23,7 +23,7 @@ import ( import ( "github.com/dubbogo/gost/container/set" - "github.com/dubbogo/gost/hash/page" + "github.com/dubbogo/gost/page" "github.com/stretchr/testify/assert" ) import ( diff --git a/registry/zookeeper/service_discovery.go b/registry/zookeeper/service_discovery.go index e5bbafd588..6d9582f33a 100644 --- a/registry/zookeeper/service_discovery.go +++ b/registry/zookeeper/service_discovery.go @@ -27,7 +27,7 @@ import ( import ( "github.com/dubbogo/gost/container/set" - "github.com/dubbogo/gost/hash/page" + "github.com/dubbogo/gost/page" perrors "github.com/pkg/errors" ) @@ -231,7 +231,7 @@ func (zksd *zookeeperServiceDiscovery) GetInstancesByPage(serviceName string, of for i := offset; i < len(all) && i < offset+pageSize; i++ { res = append(res, all[i]) } - return gxpage.NewPage(offset, pageSize, res, len(all)) + return gxpage.New(offset, pageSize, res, len(all)) } // GetHealthyInstancesByPage will return the instance @@ -254,7 +254,7 @@ func (zksd *zookeeperServiceDiscovery) GetHealthyInstancesByPage(serviceName str } i++ } - return gxpage.NewPage(offset, pageSize, res, len(all)) + return gxpage.New(offset, pageSize, res, len(all)) } // GetRequestInstances will return the instances From 15189662eff468e4073a07a61e4fb4001cfa863c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=BF=97=E4=BF=A1?= Date: Wed, 23 Dec 2020 14:50:09 +0800 Subject: [PATCH 09/39] fix: add test and fix fmt --- cluster/router/.gitkeep | 0 cluster/router/conncheck/conn_check_route.go | 5 +- .../router/conncheck/conn_check_route_test.go | 120 ++++----------- cluster/router/conncheck/conn_health_check.go | 2 +- .../conncheck/conn_health_check_test.go | 137 ++---------------- cluster/router/conncheck/factory.go | 9 +- cluster/router/conncheck/factory_test.go | 2 +- .../healthcheck/health_check_route_test.go | 4 +- protocol/rpc_status.go | 4 +- 9 files changed, 59 insertions(+), 224 deletions(-) delete mode 100644 cluster/router/.gitkeep diff --git a/cluster/router/.gitkeep b/cluster/router/.gitkeep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/cluster/router/conncheck/conn_check_route.go b/cluster/router/conncheck/conn_check_route.go index 0826821b28..8d94db409b 100644 --- a/cluster/router/conncheck/conn_check_route.go +++ b/cluster/router/conncheck/conn_check_route.go @@ -15,7 +15,7 @@ * limitations under the License. */ -package healthcheck +package conncheck import ( "github.com/RoaringBitmap/roaring" @@ -82,11 +82,12 @@ func (r *ConnCheckRouter) ShouldPool() bool { return true } +// Name get name of ConnCheckerRouter func (r *ConnCheckRouter) Name() string { return name } -// Priority +// Priority get Router priority level func (r *ConnCheckRouter) Priority() int64 { return 0 } diff --git a/cluster/router/conncheck/conn_check_route_test.go b/cluster/router/conncheck/conn_check_route_test.go index 4b9cacc17c..9c78fd3899 100644 --- a/cluster/router/conncheck/conn_check_route_test.go +++ b/cluster/router/conncheck/conn_check_route_test.go @@ -15,11 +15,10 @@ * limitations under the License. */ -package healthcheck +package conncheck import ( "fmt" - "math" "testing" "time" ) @@ -33,109 +32,54 @@ import ( "github.com/apache/dubbo-go/cluster/router/chain" "github.com/apache/dubbo-go/cluster/router/utils" "github.com/apache/dubbo-go/common" - "github.com/apache/dubbo-go/common/constant" "github.com/apache/dubbo-go/protocol" "github.com/apache/dubbo-go/protocol/invocation" ) const ( - healthCheckRoute1010IP = "192.168.10.10" - healthCheckRoute1011IP = "192.168.10.11" - healthCheckRoute1012IP = "192.168.10.12" - healthCheckRouteMethodNameTest = "test" - healthCheck1001URL = "dubbo://192.168.10.1/com.ikurento.user.UserProvider" - healthCheckRouteUrlFormat = "dubbo://%s:20000/com.ikurento.user.UserProvider" + connCheckRoute1010IP = "192.168.10.10" + connCheckRoute1011IP = "192.168.10.11" + connCheckRoute1012IP = "192.168.10.12" + connCheckRouteMethodNameTest = "test" + connCheck1001URL = "dubbo://192.168.10.1/com.ikurento.user.UserProvider" + connCheckRouteUrlFormat = "dubbo://%s:20000/com.ikurento.user.UserProvider" ) -func TestHealthCheckRouterRoute(t *testing.T) { +func TestConnCheckRouterRoute(t *testing.T) { defer protocol.CleanAllStatus() - consumerURL, _ := common.NewURL(healthCheck1001URL) - consumerURL.SetParam(CONN_ROUTE_ENABLED_KEY, "true") - url1, _ := common.NewURL(fmt.Sprintf(healthCheckRouteUrlFormat, healthCheckRoute1010IP)) - url2, _ := common.NewURL(fmt.Sprintf(healthCheckRouteUrlFormat, healthCheckRoute1011IP)) - url3, _ := common.NewURL(fmt.Sprintf(healthCheckRouteUrlFormat, healthCheckRoute1012IP)) + consumerURL, _ := common.NewURL(connCheck1001URL) + url1, _ := common.NewURL(fmt.Sprintf(connCheckRouteUrlFormat, connCheckRoute1010IP)) + url2, _ := common.NewURL(fmt.Sprintf(connCheckRouteUrlFormat, connCheckRoute1011IP)) + url3, _ := common.NewURL(fmt.Sprintf(connCheckRouteUrlFormat, connCheckRoute1012IP)) hcr, _ := NewConnCheckRouter(consumerURL) var invokers []protocol.Invoker invoker1 := NewMockInvoker(url1) invoker2 := NewMockInvoker(url2) invoker3 := NewMockInvoker(url3) + protocol.SetInvokerUnhealthyStatus(invoker1) + protocol.SetInvokerUnhealthyStatus(invoker2) + invokers = append(invokers, invoker1, invoker2, invoker3) - inv := invocation.NewRPCInvocation(healthCheckRouteMethodNameTest, nil, nil) - res := hcr.Route(utils.ToBitmap(invokers), setUpAddrCache(hcr.(*HealthCheckRouter), invokers), consumerURL, inv) + inv := invocation.NewRPCInvocation(connCheckRouteMethodNameTest, nil, nil) + res := hcr.Route(utils.ToBitmap(invokers), setUpAddrCache(hcr.(*ConnCheckRouter), invokers), consumerURL, inv) + + // now invoker3 is healthy + assert.True(t, len(res.ToArray()) == 1) + invoker2 = NewMockInvoker(url2) + + // check blacklist remove + protocol.RemoveInvokerUnhealthyStatus(invoker1) + res = hcr.Route(utils.ToBitmap(invokers), setUpAddrCache(hcr.(*ConnCheckRouter), invokers), consumerURL, inv) + // now invoker3 invoker1 is healthy + assert.True(t, len(res.ToArray()) == 2) + + // check recover + protocol.TryRefreshBlackList() + time.Sleep(time.Second) + res = hcr.Route(utils.ToBitmap(invokers), setUpAddrCache(hcr.(*ConnCheckRouter), invokers), consumerURL, inv) // now all invokers are healthy - assert.True(t, len(res.ToArray()) == len(invokers)) - - for i := 0; i < 10; i++ { - request(url1, healthCheckRouteMethodNameTest, 0, false, false) - } - res = hcr.Route(utils.ToBitmap(invokers), setUpAddrCache(hcr.(*HealthCheckRouter), invokers), consumerURL, inv) - // invokers1 is unhealthy now - assert.True(t, len(res.ToArray()) == 2 && !res.Contains(0)) - - for i := 0; i < 10; i++ { - request(url1, healthCheckRouteMethodNameTest, 0, false, false) - request(url2, healthCheckRouteMethodNameTest, 0, false, false) - } - - res = hcr.Route(utils.ToBitmap(invokers), setUpAddrCache(hcr.(*HealthCheckRouter), invokers), consumerURL, inv) - // only invokers3 is healthy now - assert.True(t, len(res.ToArray()) == 1 && !res.Contains(0) && !res.Contains(1)) - - for i := 0; i < 10; i++ { - request(url1, healthCheckRouteMethodNameTest, 0, false, false) - request(url2, healthCheckRouteMethodNameTest, 0, false, false) - request(url3, healthCheckRouteMethodNameTest, 0, false, false) - } - - res = hcr.Route(utils.ToBitmap(invokers), setUpAddrCache(hcr.(*HealthCheckRouter), invokers), consumerURL, inv) - // now all invokers are unhealthy, so downgraded to all - assert.True(t, len(res.ToArray()) == 3) - - // reset the invoker1 successive failed count, so invoker1 go to healthy - request(url1, healthCheckRouteMethodNameTest, 0, false, true) - res = hcr.Route(utils.ToBitmap(invokers), setUpAddrCache(hcr.(*HealthCheckRouter), invokers), consumerURL, inv) - assert.True(t, res.Contains(0)) - - for i := 0; i < 6; i++ { - request(url1, healthCheckRouteMethodNameTest, 0, false, false) - } - // now all invokers are unhealthy, so downgraded to all again - res = hcr.Route(utils.ToBitmap(invokers), setUpAddrCache(hcr.(*HealthCheckRouter), invokers), consumerURL, inv) assert.True(t, len(res.ToArray()) == 3) - time.Sleep(time.Second * 2) - // invoker1 go to healthy again after 2s - res = hcr.Route(utils.ToBitmap(invokers), setUpAddrCache(hcr.(*HealthCheckRouter), invokers), consumerURL, inv) - assert.True(t, res.Contains(0)) - -} - -func TestNewHealthCheckRouter(t *testing.T) { - defer protocol.CleanAllStatus() - url, _ := common.NewURL(fmt.Sprintf(healthCheckDubboUrlFormat, healthCheckDubbo1010IP)) - hcr, _ := NewHealthCheckRouter(url) - h := hcr.(*HealthCheckRouter) - assert.Nil(t, h.checker) - - url.SetParam(HEALTH_ROUTE_ENABLED_KEY, "true") - hcr, _ = NewHealthCheckRouter(url) - h = hcr.(*HealthCheckRouter) - assert.NotNil(t, h.checker) - - dhc := h.checker.(*DefaultHealthChecker) - assert.Equal(t, dhc.outStandingRequestConutLimit, int32(math.MaxInt32)) - assert.Equal(t, dhc.requestSuccessiveFailureThreshold, int32(constant.DEFAULT_SUCCESSIVE_FAILED_THRESHOLD)) - assert.Equal(t, dhc.circuitTrippedTimeoutFactor, int32(constant.DEFAULT_CIRCUIT_TRIPPED_TIMEOUT_FACTOR)) - - url.SetParam(constant.CIRCUIT_TRIPPED_TIMEOUT_FACTOR_KEY, "500") - url.SetParam(constant.SUCCESSIVE_FAILED_REQUEST_THRESHOLD_KEY, "10") - url.SetParam(constant.OUTSTANDING_REQUEST_COUNT_LIMIT_KEY, "1000") - hcr, _ = NewHealthCheckRouter(url) - h = hcr.(*HealthCheckRouter) - dhc = h.checker.(*DefaultHealthChecker) - assert.Equal(t, dhc.outStandingRequestConutLimit, int32(1000)) - assert.Equal(t, dhc.requestSuccessiveFailureThreshold, int32(10)) - assert.Equal(t, dhc.circuitTrippedTimeoutFactor, int32(500)) } func setUpAddrCache(r router.Poolable, addrs []protocol.Invoker) router.Cache { diff --git a/cluster/router/conncheck/conn_health_check.go b/cluster/router/conncheck/conn_health_check.go index 54d39f931b..9f05b0695f 100644 --- a/cluster/router/conncheck/conn_health_check.go +++ b/cluster/router/conncheck/conn_health_check.go @@ -15,7 +15,7 @@ * limitations under the License. */ -package healthcheck +package conncheck import ( "github.com/apache/dubbo-go/cluster/router" diff --git a/cluster/router/conncheck/conn_health_check_test.go b/cluster/router/conncheck/conn_health_check_test.go index 39827c5f05..7544014972 100644 --- a/cluster/router/conncheck/conn_health_check_test.go +++ b/cluster/router/conncheck/conn_health_check_test.go @@ -15,11 +15,10 @@ * limitations under the License. */ -package healthcheck +package conncheck import ( "fmt" - "math" "testing" ) @@ -29,136 +28,26 @@ import ( import ( "github.com/apache/dubbo-go/common" - "github.com/apache/dubbo-go/common/constant" "github.com/apache/dubbo-go/protocol" ) const ( - healthCheckDubbo1010IP = "192.168.10.10" - healthCheckDubbo1011IP = "192.168.10.11" - healthCheckMethodTest = "test" - healthCheckDubboUrlFormat = "dubbo://%s:20000/com.ikurento.user.UserProvider" + connCheckDubbo1010IP = "192.168.10.10" + connCheckDubboUrlFormat = "dubbo://%s:20000/com.ikurento.user.UserProvider" ) -func TestDefaultHealthCheckerIsHealthy(t *testing.T) { +func TestDefaultConnCheckerIsHealthy(t *testing.T) { defer protocol.CleanAllStatus() - url, _ := common.NewURL(fmt.Sprintf(healthCheckDubboUrlFormat, healthCheckDubbo1010IP)) - hc := NewDefaultHealthChecker(url).(*DefaultHealthChecker) + url, _ := common.NewURL(fmt.Sprintf(connCheckDubboUrlFormat, connCheckDubbo1010IP)) + cc := NewDefaultConnChecker(url).(*DefaultConnChecker) invoker := NewMockInvoker(url) - healthy := hc.IsHealthy(invoker) + healthy := cc.IsConnHealthy(invoker) assert.True(t, healthy) - url.SetParam(constant.OUTSTANDING_REQUEST_COUNT_LIMIT_KEY, "10") - url.SetParam(constant.SUCCESSIVE_FAILED_REQUEST_THRESHOLD_KEY, "100") - // fake the outgoing request - for i := 0; i < 11; i++ { - request(url, healthCheckMethodTest, 0, true, false) - } - hc = NewDefaultHealthChecker(url).(*DefaultHealthChecker) - healthy = hc.IsHealthy(invoker) - // the outgoing request is more than OUTSTANDING_REQUEST_COUNT_LIMIT, go to unhealthy - assert.False(t, hc.IsHealthy(invoker)) - - // successive failed count is more than constant.SUCCESSIVE_FAILED_REQUEST_THRESHOLD_KEY, go to unhealthy - for i := 0; i < 11; i++ { - request(url, healthCheckMethodTest, 0, false, false) - } - url.SetParam(constant.SUCCESSIVE_FAILED_REQUEST_THRESHOLD_KEY, "10") - url.SetParam(constant.OUTSTANDING_REQUEST_COUNT_LIMIT_KEY, "1000") - hc = NewDefaultHealthChecker(url).(*DefaultHealthChecker) - healthy = hc.IsHealthy(invoker) - assert.False(t, hc.IsHealthy(invoker)) - - // reset successive failed count and go to healthy - request(url, healthCheckMethodTest, 0, false, true) - healthy = hc.IsHealthy(invoker) - assert.True(t, hc.IsHealthy(invoker)) -} - -func TestDefaultHealthCheckerGetCircuitBreakerSleepWindowTime(t *testing.T) { - defer protocol.CleanAllStatus() - url, _ := common.NewURL(fmt.Sprintf(healthCheckDubboUrlFormat, healthCheckDubbo1010IP)) - defaultHc := NewDefaultHealthChecker(url).(*DefaultHealthChecker) - // Increase the number of failed requests - for i := 0; i < 100; i++ { - request(url, healthCheckMethodTest, 1, false, false) - } - sleepWindowTime := defaultHc.getCircuitBreakerSleepWindowTime(protocol.GetURLStatus(url)) - assert.True(t, sleepWindowTime == constant.MAX_CIRCUIT_TRIPPED_TIMEOUT_IN_MS) - - // Adjust the threshold size to 1000 - url.SetParam(constant.SUCCESSIVE_FAILED_REQUEST_THRESHOLD_KEY, "1000") - sleepWindowTime = NewDefaultHealthChecker(url).(*DefaultHealthChecker).getCircuitBreakerSleepWindowTime(protocol.GetURLStatus(url)) - assert.True(t, sleepWindowTime == 0) - - url1, _ := common.NewURL(fmt.Sprintf(healthCheckDubboUrlFormat, healthCheckDubbo1011IP)) - sleepWindowTime = defaultHc.getCircuitBreakerSleepWindowTime(protocol.GetURLStatus(url1)) - assert.True(t, sleepWindowTime == 0) - request(url1, healthCheckMethodTest, 1, false, false) - request(url1, healthCheckMethodTest, 1, false, false) - request(url1, healthCheckMethodTest, 1, false, false) - request(url1, healthCheckMethodTest, 1, false, false) - request(url1, healthCheckMethodTest, 1, false, false) - request(url1, healthCheckMethodTest, 1, false, false) - sleepWindowTime = defaultHc.getCircuitBreakerSleepWindowTime(protocol.GetURLStatus(url1)) - assert.True(t, sleepWindowTime > 0 && sleepWindowTime < constant.MAX_CIRCUIT_TRIPPED_TIMEOUT_IN_MS) -} - -func TestDefaultHealthCheckerGetCircuitBreakerTimeout(t *testing.T) { - defer protocol.CleanAllStatus() - url, _ := common.NewURL(fmt.Sprintf(healthCheckDubboUrlFormat, healthCheckDubbo1010IP)) - defaultHc := NewDefaultHealthChecker(url).(*DefaultHealthChecker) - timeout := defaultHc.getCircuitBreakerTimeout(protocol.GetURLStatus(url)) - assert.True(t, timeout == 0) - url1, _ := common.NewURL(fmt.Sprintf(healthCheckDubboUrlFormat, healthCheckDubbo1011IP)) - request(url1, healthCheckMethodTest, 1, false, false) - request(url1, healthCheckMethodTest, 1, false, false) - request(url1, healthCheckMethodTest, 1, false, false) - request(url1, healthCheckMethodTest, 1, false, false) - request(url1, healthCheckMethodTest, 1, false, false) - request(url1, healthCheckMethodTest, 1, false, false) - timeout = defaultHc.getCircuitBreakerTimeout(protocol.GetURLStatus(url1)) - // timeout must after the current time - assert.True(t, timeout > protocol.CurrentTimeMillis()) - -} - -func TestDefaultHealthCheckerIsCircuitBreakerTripped(t *testing.T) { - defer protocol.CleanAllStatus() - url, _ := common.NewURL(fmt.Sprintf(healthCheckDubboUrlFormat, healthCheckDubbo1010IP)) - defaultHc := NewDefaultHealthChecker(url).(*DefaultHealthChecker) - status := protocol.GetURLStatus(url) - tripped := defaultHc.isCircuitBreakerTripped(status) - assert.False(t, tripped) - // Increase the number of failed requests - for i := 0; i < 100; i++ { - request(url, healthCheckMethodTest, 1, false, false) - } - tripped = defaultHc.isCircuitBreakerTripped(protocol.GetURLStatus(url)) - assert.True(t, tripped) - -} - -func TestNewDefaultHealthChecker(t *testing.T) { - defer protocol.CleanAllStatus() - url, _ := common.NewURL(fmt.Sprintf(healthCheckDubboUrlFormat, healthCheckDubbo1010IP)) - defaultHc := NewDefaultHealthChecker(url).(*DefaultHealthChecker) - assert.NotNil(t, defaultHc) - assert.Equal(t, defaultHc.outStandingRequestConutLimit, int32(math.MaxInt32)) - assert.Equal(t, defaultHc.requestSuccessiveFailureThreshold, int32(constant.DEFAULT_SUCCESSIVE_FAILED_REQUEST_MAX_DIFF)) - - url1, _ := common.NewURL(fmt.Sprintf(healthCheckDubboUrlFormat, healthCheckDubbo1010IP)) - url1.SetParam(constant.OUTSTANDING_REQUEST_COUNT_LIMIT_KEY, "10") - url1.SetParam(constant.SUCCESSIVE_FAILED_REQUEST_THRESHOLD_KEY, "10") - nondefaultHc := NewDefaultHealthChecker(url1).(*DefaultHealthChecker) - assert.NotNil(t, nondefaultHc) - assert.Equal(t, nondefaultHc.outStandingRequestConutLimit, int32(10)) - assert.Equal(t, nondefaultHc.requestSuccessiveFailureThreshold, int32(10)) -} - -func request(url *common.URL, method string, elapsed int64, active, succeeded bool) { - protocol.BeginCount(url, method) - if !active { - protocol.EndCount(url, method, elapsed, succeeded) - } + invoker = NewMockInvoker(url) + cc = NewDefaultConnChecker(url).(*DefaultConnChecker) + healthy = cc.IsConnHealthy(invoker) + // add to black list + protocol.SetInvokerUnhealthyStatus(invoker) + assert.False(t, cc.IsConnHealthy(invoker)) } diff --git a/cluster/router/conncheck/factory.go b/cluster/router/conncheck/factory.go index 05d6a3815e..12498d18d8 100644 --- a/cluster/router/conncheck/factory.go +++ b/cluster/router/conncheck/factory.go @@ -15,7 +15,7 @@ * limitations under the License. */ -package healthcheck +package conncheck import ( "github.com/apache/dubbo-go/cluster/router" @@ -28,16 +28,17 @@ func init() { extension.SetRouterFactory(constant.ConnCheckRouterName, newConnCheckRouteFactory) } -// ConnCheckRouteFactory +// ConnCheckRouteFactory is the factory to create conn check router, it aims at filter ip with unhealthy status +// the unhealthy status is storied in protocol/rpc_status.go with sync.Map type ConnCheckRouteFactory struct { } -// newHealthCheckRouteFactory construct a new HealthCheckRouteFactory +// newConnCheckRouteFactory construct a new ConnCheckRouteFactory func newConnCheckRouteFactory() router.PriorityRouterFactory { return &ConnCheckRouteFactory{} } -// NewPriorityRouter construct a new NewHealthCheckRouter via url +// NewPriorityRouter construct a new NewConnCheckRouter via url func (f *ConnCheckRouteFactory) NewPriorityRouter(url *common.URL) (router.PriorityRouter, error) { return NewConnCheckRouter(url) } diff --git a/cluster/router/conncheck/factory_test.go b/cluster/router/conncheck/factory_test.go index 9e1870ae98..02f8fb472e 100644 --- a/cluster/router/conncheck/factory_test.go +++ b/cluster/router/conncheck/factory_test.go @@ -15,7 +15,7 @@ * limitations under the License. */ -package healthcheck +package conncheck import ( "context" diff --git a/cluster/router/healthcheck/health_check_route_test.go b/cluster/router/healthcheck/health_check_route_test.go index 0730f105b7..f088be531a 100644 --- a/cluster/router/healthcheck/health_check_route_test.go +++ b/cluster/router/healthcheck/health_check_route_test.go @@ -50,7 +50,7 @@ const ( func TestHealthCheckRouterRoute(t *testing.T) { defer protocol.CleanAllStatus() consumerURL, _ := common.NewURL(healthCheck1001URL) - consumerURL.SetParam(HEALTH_ROUTE_ENABLED_KEY, "true") + consumerURL.SetParam(constant.HEALTH_ROUTE_ENABLED_KEY, "true") url1, _ := common.NewURL(fmt.Sprintf(healthCheckRouteUrlFormat, healthCheckRoute1010IP)) url2, _ := common.NewURL(fmt.Sprintf(healthCheckRouteUrlFormat, healthCheckRoute1011IP)) url3, _ := common.NewURL(fmt.Sprintf(healthCheckRouteUrlFormat, healthCheckRoute1012IP)) @@ -117,7 +117,7 @@ func TestNewHealthCheckRouter(t *testing.T) { h := hcr.(*HealthCheckRouter) assert.Nil(t, h.checker) - url.SetParam(HEALTH_ROUTE_ENABLED_KEY, "true") + url.SetParam(constant.HEALTH_ROUTE_ENABLED_KEY, "true") hcr, _ = NewHealthCheckRouter(url) h = hcr.(*HealthCheckRouter) assert.NotNil(t, h.checker) diff --git a/protocol/rpc_status.go b/protocol/rpc_status.go index d4988cd938..54435f156c 100644 --- a/protocol/rpc_status.go +++ b/protocol/rpc_status.go @@ -18,8 +18,6 @@ package protocol import ( - "github.com/apache/dubbo-go/common/constant" - "github.com/apache/dubbo-go/common/logger" "sync" "sync/atomic" "time" @@ -27,6 +25,8 @@ import ( import ( "github.com/apache/dubbo-go/common" + "github.com/apache/dubbo-go/common/constant" + "github.com/apache/dubbo-go/common/logger" ) var ( From 2831e35956f851113138c29f2ad258aea0ab12e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=BF=97=E4=BF=A1?= Date: Wed, 23 Dec 2020 15:07:46 +0800 Subject: [PATCH 10/39] fix: go fmt project --- protocol/rpc_status.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/protocol/rpc_status.go b/protocol/rpc_status.go index 54435f156c..1e0b311e27 100644 --- a/protocol/rpc_status.go +++ b/protocol/rpc_status.go @@ -192,19 +192,23 @@ func CleanAllStatus() { invokerBlackList.Range(delete3) } +// GetInvokerHealthyStatus get invoker's conn healthy status func GetInvokerHealthyStatus(invoker Invoker) bool { _, found := invokerBlackList.Load(invoker.GetUrl().Key()) return !found } +// SetInvokerUnhealthyStatus add target invoker to black list func SetInvokerUnhealthyStatus(invoker Invoker) { invokerBlackList.Store(invoker.GetUrl().Key(), invoker) } +// RemoveInvokerUnhealthyStatus remove unhealthy status of target invoker from blacklist func RemoveInvokerUnhealthyStatus(invoker Invoker) { invokerBlackList.Delete(invoker.GetUrl().Key()) } +// GetBlackListInvokers get at most size of blockSize invokers from black list func GetBlackListInvokers(blockSize int) []Invoker { resultIvks := make([]Invoker, 0, 16) invokerBlackList.Range(func(k, v interface{}) bool { @@ -222,6 +226,8 @@ func RemoveUrlKeyUnhealthyStatus(key string) { invokerBlackList.Delete(key) } +// TryRefreshBlackList start 3 gr to check at most block=16 invokers in black list +// if is available remove from black list func TryRefreshBlackList() { if atomic.CompareAndSwapInt32(&blackListRefreshing, 0, 1) { wg := sync.WaitGroup{} From ae8b2ae93a027a3c429a9168edf0df4279b347bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=BF=97=E4=BF=A1?= Date: Sun, 27 Dec 2020 17:01:10 +0800 Subject: [PATCH 11/39] fix: go mod tidy --- go.sum | 182 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 182 insertions(+) diff --git a/go.sum b/go.sum index 29b0df7d98..ab1179397b 100644 --- a/go.sum +++ b/go.sum @@ -238,6 +238,7 @@ github.com/dubbogo/gost v1.9.0/go.mod h1:pPTjVyoJan3aPxBPNUX0ADkXjPibLo+/Ib0/fAD github.com/dubbogo/gost v1.9.5 h1:UeG4y0O55lR3dzgdmCm/7bMWvpKrlpR7fsfKjrcXq/g= github.com/dubbogo/gost v1.9.5/go.mod h1:QNM5RaeRdNWehUu8S0hUP5Qa8QUfGf6KH1JhqOVFvEI= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= @@ -245,27 +246,37 @@ github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFP github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/ef-ds/deque v1.0.4-0.20190904040645-54cb57c252a1/go.mod h1:HvODWzv6Y6kBf3Ah2WzN1bHjDUezGLaAhwuWVwfpEJs= github.com/elazarl/go-bindata-assetfs v0.0.0-20160803192304-e1a2a7ec64b0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4= +github.com/elazarl/go-bindata-assetfs v1.0.0 h1:G/bYguwHIzWq9ZoyUQqrjTmJbbYn3j3CKKpKinvZLFk= github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4= github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= +github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633 h1:H2pdYOb3KQ1/YsqVWoWNLQO+fusocsw354rqGTZtAgw= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/emicklei/go-restful/v3 v3.4.0 h1:IIDhql3oyWZj1ay2xBZGb4sTOWMad0HVW8rwhVxN/Yk= github.com/emicklei/go-restful/v3 v3.4.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= +github.com/envoyproxy/go-control-plane v0.8.0 h1:uE6Fp4fOcAJdc1wTQXLJ+SYistkbG1dNoi6Zs1+Ybvk= github.com/envoyproxy/go-control-plane v0.8.0/go.mod h1:GSSbY9P1neVhdY7G4wu+IK1rk/dqhiCC/4ExuWJZVuk= github.com/envoyproxy/protoc-gen-validate v0.0.14/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/evanphx/json-patch v4.2.0+incompatible h1:fUDGZCv/7iAN7u0puUVhvKCcsR6vRfwrJatElLBEf0I= github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch/v5 v5.0.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= github.com/exoscale/egoscale v0.18.1/go.mod h1:Z7OOdzzTOz1Q1PjQXumlz9Wn/CddH0zSYdCF3rnBKXE= +github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 h1:Ghm4eQYC0nEPnSJdVkTrXpu9KtoVCSo1hg7mtI7G9KU= github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239/go.mod h1:Gdwt2ce0yfBxPvZrHkprdPPTTS3N5rwmLE8T22KBXlw= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/forestgiant/sliceutil v0.0.0-20160425183142-94783f95db6c/go.mod h1:pFdJbAhRf7rh6YYMUdIQGyzne6zYL1tCUW8QV2B3UfY= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= +github.com/frankban/quicktest v1.4.1 h1:Wv2VwvNn73pAdFIVUQRXYDFp31lXKbqblIXo/Q5GPSg= github.com/frankban/quicktest v1.4.1/go.mod h1:36zfPVQyHxymz4cH7wlDmVwDrJuljRB60qkgn7rorfQ= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsouza/go-dockerclient v1.6.0/go.mod h1:YWwtNPuL4XTX1SKJQk86cWPmmqwx+4np9qfPbb+znGc= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= @@ -275,12 +286,15 @@ github.com/gin-gonic/gin v1.5.0/go.mod h1:Nd6IXA8m5kNZdNEHMBd93KT+mdY3+bewLgRvmC github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/glycerine/go-unsnap-stream v0.0.0-20181221182339-f9677308dec2 h1:Ujru1hufTHVb++eG6OuNDKMxZnGIvF6o/u8q/8h2+I4= github.com/glycerine/go-unsnap-stream v0.0.0-20181221182339-f9677308dec2/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE= +github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31 h1:gclg6gY70GLy3PbkQ1AERPfmLMMagS60DKF78eWwLn8= github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24= github.com/go-acme/lego/v3 v3.4.0/go.mod h1:xYbLDuxq3Hy4bMUT1t9JIuz6GWIWb3m5X+TeTHYaT7M= github.com/go-asn1-ber/asn1-ber v1.3.1/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= github.com/go-check/check v0.0.0-20140225173054-eb6ee6f84d0a/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= github.com/go-cmd/cmd v1.0.5/go.mod h1:y8q8qlK5wQibcw63djSl/ntiHUHXHGdCkPk0j4QeW4s= +github.com/go-co-op/gocron v0.1.1 h1:OfDmkqkCguFtFMsm6Eaayci3DADLa8pXvdmOlPU/JcU= github.com/go-co-op/gocron v0.1.1/go.mod h1:Y9PWlYqDChf2Nbgg7kfS+ZsXHDTZbMZYPEQ0MILqH+M= +github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= @@ -299,6 +313,7 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= +github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI= github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM= github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= @@ -307,32 +322,39 @@ github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dp github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM= github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY= github.com/go-redis/redis v6.15.5+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= +github.com/go-resty/resty/v2 v2.3.0 h1:JOOeAvjSlapTT92p8xiS19Zxev1neGikoHsXJeOq8So= github.com/go-resty/resty/v2 v2.3.0/go.mod h1:UpN9CgLZNsv4e9XG50UU8xdI0F43UQ4HmxLBDwaroHU= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible/go.mod h1:qf9acutJ8cwBUhm1bqgz6Bei9/C/c93FPDljKWwsOgM= github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= +github.com/go-test/deep v1.0.2 h1:onZX1rnHT3Wv6cqNgYyFOOlgVKJrksuCMCRvJStbMYw= github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.0.3/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gogo/googleapis v1.1.0 h1:kFkMAZBNAn4j7K0GiZr8cRYzejq68VbheufiV3YuyFI= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -346,34 +368,45 @@ github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrU github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-querystring v0.0.0-20170111101155-53e6ce116135/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= +github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/tcpproxy v0.0.0-20180808230851-dfa16c61dad2 h1:AtvtonGEH/fZK0XPNNBdB6swgy7Iudfx88wzyIpwqJ8= github.com/google/tcpproxy v0.0.0-20180808230851-dfa16c61dad2/go.mod h1:DavVbd41y+b7ukKDmlnPR4nGYmkWXR6vHUkjQNiHPBs= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.2.0 h1:l6N3VoaVzTncYYW+9yOz2LJJammFZGBO13sqgEhpy9g= github.com/googleapis/gnostic v0.2.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= +github.com/gophercloud/gophercloud v0.3.0 h1:6sjpKIpVwRIIwmcEGp+WwNovNsem+c+2vm6oxshRpL8= github.com/gophercloud/gophercloud v0.3.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gopherjs/gopherjs v0.0.0-20190910122728-9d188e94fb99 h1:twflg0XRTjwKpxb/jFExr4HGq6on2dEOmnL6FV+fgPw= github.com/gopherjs/gopherjs v0.0.0-20190910122728-9d188e94fb99/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= @@ -388,108 +421,152 @@ github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/ad github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.1.0 h1:THDBEeQ9xZ8JEaCLyLQqXMMdRqNr0QAUJTIkQAUtFjg= github.com/grpc-ecosystem/go-grpc-middleware v1.1.0/go.mod h1:f5nM7jw/oeRSadq3xCzHAvxcr8HZnzsqU6ILg/0NiiE= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.9.5 h1:UImYN5qQ8tuGpGE16ZmjvcTtTw24zw1QAp/SlnNrZhI= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 h1:MJG/KsmcqMwFAkh8mTnAwhyKoB+sTAnY4CACC110tbU= github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645/go.mod h1:6iZfnjpejD4L/4DwD7NryNaJyCQdzwWwH2MWhCA90Kw= github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI= +github.com/hashicorp/consul v1.8.0 h1:yRKMKZyPLqUxl37t4nFt5OuGmTXoFhTJrakhfnYKCYA= github.com/hashicorp/consul v1.8.0/go.mod h1:Gg9/UgAQ9rdY3CTvzQZ6g2jcIb7NlIfjI+0pvLk5D1A= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= github.com/hashicorp/consul/api v1.4.0/go.mod h1:xc8u05kyMa3Wjr9eEAsIAo3dg8+LywT5E/Cl7cNS5nU= +github.com/hashicorp/consul/api v1.5.0 h1:Yo2bneoGy68A7aNwmuETFnPhjyBEm7n3vzRacEVMjvI= github.com/hashicorp/consul/api v1.5.0/go.mod h1:LqwrLNW876eYSuUOo4ZLHBcdKc038txr/IMfbLPATa4= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/consul/sdk v0.4.0/go.mod h1:fY08Y9z5SvJqevyZNy6WWPXiG3KwBPAvlcdx16zZ0fM= +github.com/hashicorp/consul/sdk v0.5.0 h1:WC4594Wp/LkEeML/OdQKEC1yqBmEYkRp6i7X5u0zDAs= github.com/hashicorp/consul/sdk v0.5.0/go.mod h1:fY08Y9z5SvJqevyZNy6WWPXiG3KwBPAvlcdx16zZ0fM= github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-bexpr v0.1.2 h1:ijMXI4qERbzxbCnkxmfUtwMyjrrk3y+Vt0MxojNCbBs= github.com/hashicorp/go-bexpr v0.1.2/go.mod h1:ANbpTX1oAql27TZkKVeW8p1w8NTdnyzPe/0qqPCKohU= github.com/hashicorp/go-checkpoint v0.0.0-20171009173528-1545e56e46de/go.mod h1:xIwEieBHERyEvaeKF/TcHh1Hu+lxPM+n2vT1+g9I4m4= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-connlimit v0.2.0 h1:OZjcfNxH/hPh/bT2Iw5yOJcLzz+zuIWpsp3I1S4Pjw4= github.com/hashicorp/go-connlimit v0.2.0/go.mod h1:OUj9FGL1tPIhl/2RCfzYHrIiWj+VVPGNyVPnUX8AqS0= +github.com/hashicorp/go-discover v0.0.0-20200501174627-ad1e96bde088 h1:jBvElOilnIl6mm8S6gva/dfeTJCcMs9TGO6/2C6k52E= github.com/hashicorp/go-discover v0.0.0-20200501174627-ad1e96bde088/go.mod h1:vZu6Opqf49xX5lsFAu7iFNewkcVF1sn/wyapZh5ytlg= github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI= github.com/hashicorp/go-hclog v0.8.0/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= github.com/hashicorp/go-hclog v0.9.1/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= +github.com/hashicorp/go-hclog v0.12.0 h1:d4QkX8FRTYaKaCZBoXYY8zJX2BXjWxurN/GA2tkrmZM= github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-immutable-radix v1.1.0 h1:vN9wG1D6KG6YHRTWr8512cxGOVgTMEfgEdSj/hr8MPc= github.com/hashicorp/go-immutable-radix v1.1.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-memdb v1.0.3 h1:iiqzNk8jKB6/sLRj623Ui/Vi1zf21LOUpgzGjTge6a8= github.com/hashicorp/go-memdb v1.0.3/go.mod h1:LWQ8R70vPrS4OEY9k28D2z8/Zzyu34NVzeRibGAzHO0= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-msgpack v0.5.5 h1:i9R9JSrqIz0QVLz3sz+i3YJdT7TTSLcfLLzJi9aZTuI= github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-multierror v1.1.0 h1:B9UzwGQJehnUY1yNrnwREHc3fGbC2xefo8g4TbElacI= github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= github.com/hashicorp/go-plugin v1.0.1/go.mod h1:++UyYGoz3o5w9ZzAdZxtQKrWWP+iqPBn3cQptSMzBuY= github.com/hashicorp/go-raftchunking v0.6.1/go.mod h1:cGlg3JtDy7qy6c/3Bu660Mic1JF+7lWqIwCFSb08fX0= +github.com/hashicorp/go-raftchunking v0.6.3-0.20191002164813-7e9e8525653a h1:FmnBDwGwlTgugDGbVxwV8UavqSMACbGrUpfc98yFLR4= github.com/hashicorp/go-raftchunking v0.6.3-0.20191002164813-7e9e8525653a/go.mod h1:xbXnmKqX9/+RhPkJ4zrEx4738HacP72aaUPlT2RZ4sU= github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= github.com/hashicorp/go-retryablehttp v0.5.4/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= +github.com/hashicorp/go-retryablehttp v0.6.2 h1:bHM2aVXwBtBJWxHtkSrWuI4umABCUczs52eiUS9nSiw= github.com/hashicorp/go-retryablehttp v0.6.2/go.mod h1:gEx6HMUGxYYhJScX7W1Il64m6cc2C1mDaW3NQ9sY1FY= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= github.com/hashicorp/go-rootcerts v1.0.1/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= +github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc= github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A= +github.com/hashicorp/go-syslog v1.0.0 h1:KaodqZuhUoZereWVIYmpUgZysurB1kBLX2j0MwMrUAE= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.2-0.20191001231223-f32f5fe8d6a8/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.2.0 h1:3vNe/fWF5CBgRIguda1meWhsZHy3m8gCJ5wx+dIzX/E= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk= github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/hil v0.0.0-20160711231837-1e86c6b523c5 h1:uk280DXEbQiCOZgCOI3elFSeNxf8YIZiNsbr2pQLYD0= github.com/hashicorp/hil v0.0.0-20160711231837-1e86c6b523c5/go.mod h1:KHvg/R2/dPtaePb16oW4qIyzkMxXOL38xjRN64adsts= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/mdns v1.0.1 h1:XFSOubp8KWB+Jd2PDyaX5xUd5bhSP/+pTDZVDMzZJM8= github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/memberlist v0.2.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= +github.com/hashicorp/memberlist v0.2.2 h1:5+RffWKwqJ71YPu9mWsF7ZOscZmwfasdA8kbdC7AO2g= github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= +github.com/hashicorp/net-rpc-msgpackrpc v0.0.0-20151116020338-a14192a58a69 h1:lc3c72qGlIMDqQpQH82Y4vaglRMMFdJbziYWriR4UcE= github.com/hashicorp/net-rpc-msgpackrpc v0.0.0-20151116020338-a14192a58a69/go.mod h1:/z+jUGRBlwVpUZfjute9jWaF6/HuhjuFQuL1YXzVD1Q= github.com/hashicorp/raft v1.1.1/go.mod h1:vPAJM8Asw6u8LxC3eJCUZmRP/E4QmUGE1R7g7k8sG/8= github.com/hashicorp/raft v1.1.2-0.20191002163536-9c6bd3e3eb17/go.mod h1:vPAJM8Asw6u8LxC3eJCUZmRP/E4QmUGE1R7g7k8sG/8= +github.com/hashicorp/raft v1.1.2 h1:oxEL5DDeurYxLd3UbcY/hccgSPhLLpiBZ1YxtWEq59c= github.com/hashicorp/raft v1.1.2/go.mod h1:vPAJM8Asw6u8LxC3eJCUZmRP/E4QmUGE1R7g7k8sG/8= +github.com/hashicorp/raft-boltdb v0.0.0-20171010151810-6e5ba93211ea h1:xykPFhrBAS2J0VBzVa5e80b5ZtYuNQtgXjN40qBZlD4= github.com/hashicorp/raft-boltdb v0.0.0-20171010151810-6e5ba93211ea/go.mod h1:pNv7Wc3ycL6F5oOWn+tPGo2gWD4a5X+yp/ntwdKLjRk= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hashicorp/serf v0.9.0/go.mod h1:YL0HO+FifKOW2u1ke99DGVu1zhcpZzNwrLIqBC7vbYU= +github.com/hashicorp/serf v0.9.2 h1:yJoyfZXo4Pk2p/M/viW+YLibBFiIbKoP79gu7kDAFP0= github.com/hashicorp/serf v0.9.2/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk= github.com/hashicorp/vault/api v1.0.4/go.mod h1:gDcqh3WGcR1cpF5AJz/B1UFheUEneMoIospckxBxk6Q= +github.com/hashicorp/vault/api v1.0.5-0.20191108163347-bdd38fca2cff h1:cl94LQIrs/mNbh3ny1R8lM1gtYcUBa7HnGtOCi35SlQ= github.com/hashicorp/vault/api v1.0.5-0.20191108163347-bdd38fca2cff/go.mod h1:Uf8LaHyrYsgVgHzO2tMZKhqRGlL3UJ6XaSwW2EA1Iqo= github.com/hashicorp/vault/sdk v0.1.13/go.mod h1:B+hVj7TpuQY1Y/GPbCpffmgd+tSEwvhkWnjtSYCaS2M= github.com/hashicorp/vault/sdk v0.1.14-0.20191108161836-82f2b5571044/go.mod h1:PcekaFGiPJyHnFy+NZhP6ll650zEw51Ag7g/YEa+EOU= +github.com/hashicorp/vault/sdk v0.1.14-0.20191112033314-390e96e22eb2 h1:mKYi4Fm2uSfe94Ji89CoAaP7SPEEkfdtaUlgRGGb2go= github.com/hashicorp/vault/sdk v0.1.14-0.20191112033314-390e96e22eb2/go.mod h1:PcekaFGiPJyHnFy+NZhP6ll650zEw51Ag7g/YEa+EOU= +github.com/hashicorp/vic v1.5.1-0.20190403131502-bbfe86ec9443 h1:O/pT5C1Q3mVXMyuqg7yuAWUg/jMZR1/0QTzTRdNR6Uw= github.com/hashicorp/vic v1.5.1-0.20190403131502-bbfe86ec9443/go.mod h1:bEpDU35nTu0ey1EXjwNwPjI9xErAsoOCmcMb9GKvyxo= github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= +github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d h1:kJCB4vdITiW1eC1vq2e6IsrXKrZit1bv/TDYFGMp4BQ= github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/iij/doapi v0.0.0-20190504054126-0bbf12d6d7df/go.mod h1:QMZY7/J/KSQEhKWFeDesPjMj+wCHReeknARU3wqlyN4= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.9 h1:UauaLniWCFHWd+Jp9oCEkTBj8VO/9DKg3PV3VCNMDIg= github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ= github.com/jackc/pgx v3.3.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I= +github.com/jarcoal/httpmock v0.0.0-20180424175123-9c70cfe4a1da h1:FjHUJJ7oBW4G/9j1KzlHaXL09LyMVM9rupS39lncbXk= github.com/jarcoal/httpmock v0.0.0-20180424175123-9c70cfe4a1da/go.mod h1:ks+b9deReOc7jgqp+e7LuFiCBH6Rm5hL32cLcEAArb4= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= +github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 h1:IPJ3dvxmJ4uczJe5YQdrYB16oTJlGSC/OyZDqUk9xX4= github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869/go.mod h1:cJ6Cj7dQo+O6GJNiMx+Pa94qKj+TG8ONdKHgMNIyyag= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jinzhu/copier v0.0.0-20190625015134-976e0346caa8 h1:mGIXW/lubQ4B+3bXTLxcTMTjUNDqoF6T/HUW9LbFx9s= github.com/jinzhu/copier v0.0.0-20190625015134-976e0346caa8/go.mod h1:yL958EeXv8Ylng6IfnvG4oflryUi3vgA3xPs9hmII1s= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/joyent/triton-go v0.0.0-20180628001255-830d2b111e62/go.mod h1:U+RSyWxWd04xTqnuOQxnai7XGS2PrPY2cfGoDKtMHjA= +github.com/joyent/triton-go v1.7.1-0.20200416154420-6801d15b779f h1:ENpDacvnr8faw5ugQmEF1QYk+f/Y9lXFvuYmRxykago= github.com/joyent/triton-go v1.7.1-0.20200416154420-6801d15b779f/go.mod h1:KDSfL7qe5ZfQqvlDMkVjCztbmcpp/c8M77vhQP8ZPvk= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= @@ -498,8 +575,10 @@ github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCV github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= @@ -513,26 +592,33 @@ github.com/klauspost/cpuid v1.2.3/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgo github.com/kolo/xmlrpc v0.0.0-20190717152603-07c4ee3fd181/go.mod h1:o03bZfuBwAXHetKXuInt4S7omeXUu62/A845kiycsSQ= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/labbsr0x/bindman-dns-webhook v1.0.2/go.mod h1:p6b+VCXIR8NYKpDr8/dg1HKfQoRHCdcsROXKvmoehKA= github.com/labbsr0x/goh v1.0.1/go.mod h1:8K2UhVoaWXcCU7Lxoa2omWnC8gyW8px7/lmO61c027w= github.com/labstack/echo/v4 v4.1.15/go.mod h1:GWO5IBVzI371K8XJe50CSvHjQCafK6cw8R/moLhEU6o= github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw= +github.com/lestrrat/go-envload v0.0.0-20180220120943-6ed08b54a570 h1:0iQektZGS248WXmGIYOwRXSQhD4qn3icjMpuxwO7qlo= github.com/lestrrat/go-envload v0.0.0-20180220120943-6ed08b54a570/go.mod h1:BLt8L9ld7wVsvEWQbuLrUZnCMnUmLZ+CGDzKtclrTlE= +github.com/lestrrat/go-file-rotatelogs v0.0.0-20180223000712-d3151e2a480f h1:sgUSP4zdTUZYZgAGGtN5Lxk92rK+JUFOwf+FT99EEI4= github.com/lestrrat/go-file-rotatelogs v0.0.0-20180223000712-d3151e2a480f/go.mod h1:UGmTpUd3rjbtfIpwAPrcfmGf/Z1HS95TATB+m57TPB8= +github.com/lestrrat/go-strftime v0.0.0-20180220042222-ba3bf9c1d042 h1:Bvq8AziQ5jFF4BHGAEDSqwPW1NJS3XshxbRCxtjFAZc= github.com/lestrrat/go-strftime v0.0.0-20180220042222-ba3bf9c1d042/go.mod h1:TPpsiPUEh0zFL1Snz4crhMlBe60PYxRHr5oFF3rRYg0= github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= github.com/linode/linodego v0.7.1/go.mod h1:ga11n3ivecUrPCHN0rANxKmfWBJVkOXfLMZinAbj2sY= +github.com/linode/linodego v0.10.0 h1:AMdb82HVgY8o3mjBXJcUv9B+fnJjfDMn2rNRGbX+jvM= github.com/linode/linodego v0.10.0/go.mod h1:cziNP7pbvE3mXIPneHj0oRY8L1WtGEIKlZ8LANE4eXA= github.com/liquidweb/liquidweb-go v1.6.0/go.mod h1:UDcVnAMDkZxpw4Y7NOHkqoeiGacVLEIG/i5J9cyixzQ= github.com/lucas-clemente/quic-go v0.14.1/go.mod h1:Vn3/Fb0/77b02SGhQk36KzOUmXgVpFfizUfW5WMaqyU= @@ -549,6 +635,7 @@ github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaO github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.7 h1:bQGKb3vps/j0E9GfJQ03JyhRuxsvdAanXlT9BTw3mdw= github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= @@ -556,51 +643,66 @@ github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= +github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-tty v0.0.0-20180219170247-931426f7535a/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE= +github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/micro/cli/v2 v2.1.2/go.mod h1:EguNh6DAoWKm9nmk+k/Rg0H3lQnDxqzu5x5srOtGtYg= github.com/micro/go-micro/v2 v2.9.1/go.mod h1:x55ZM3Puy0FyvvkR3e0ha0xsE9DFwfPSUMWAIbFY0SY= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.15/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= +github.com/miekg/dns v1.1.27 h1:aEH/kqUzUxGJ/UHcEKdJY+ugH6WEzsEBBSPa8zuy1aM= github.com/miekg/dns v1.1.27/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/cli v1.1.0 h1:tEElEatulEHDeedTxwckzyYMA5c86fbmNIUL1hBIiTg= github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= +github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/go-testing-interface v1.14.0 h1:/x0XQ6h+3U3nAyk1yx+bHPURrKa9sVVvYbuqZ7pIAtI= github.com/mitchellh/go-testing-interface v1.14.0/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= github.com/mitchellh/go-vnc v0.0.0-20150629162542-723ed9867aed/go.mod h1:3rdaFaCv4AyBgu5ALFM0+tSuHrBh6v692nyQe3ikrq0= github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ= +github.com/mitchellh/hashstructure v1.0.0 h1:ZkRJX1CyOoTkar7p/mLS5TZU4nJ1Rn/F8u9dGS02Q3Y= github.com/mitchellh/hashstructure v1.0.0/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.2.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.0 h1:7ks8ZkOP5/ujthUsT07rNv+nkLXCQWKNHuwzOAesEks= github.com/mitchellh/mapstructure v1.4.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/pointerstructure v1.0.0 h1:ATSdz4NWrmWPOF1CeCBU4sMCno2hgqdbSrRPFWQSVZI= github.com/mitchellh/pointerstructure v1.0.0/go.mod h1:k4XwG94++jLVsSiTxo7qdIfXA9pj9EAeo0QsNNJOLZ8= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/mitchellh/reflectwalk v1.0.1 h1:FVzMWA5RllMAKIdUSC8mdWo3XtwoecrH79BY70sEEpE= github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= +github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae h1:VeRdUYdCw49yizlSbMEn2SZ+gT+3IUKx8BqxyQdz+BY= github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/nacos-group/nacos-sdk-go v1.0.0/go.mod h1:hlAPn3UdzlxIlSILAyOXKxjFSvDJ9oLzTJ9hLAK1KzA= +github.com/nacos-group/nacos-sdk-go v1.0.1 h1:VNmXGlSS28xOmkO5Nxk5WRp6f1HMosAmG9pDtcnUFcw= github.com/nacos-group/nacos-sdk-go v1.0.1/go.mod h1:hlAPn3UdzlxIlSILAyOXKxjFSvDJ9oLzTJ9hLAK1KzA= github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04/go.mod h1:5sN+Lt1CaY4wsPvgQH/jsuJi4XO2ssZbdsIizr4CVC8= github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= @@ -614,7 +716,9 @@ github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxzi github.com/nats-io/nkeys v0.1.4/go.mod h1:XdZpAbhgyyODYqjTawOnIOI7VlbKSarI9Gfy1tqEu/s= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms= +github.com/nicolai86/scaleway-sdk v1.10.2-0.20180628010248-798f60e20bb2 h1:BQ1HW7hr4IVovMwWg0E0PYcyW8CzqDcVmaew9cujU4s= github.com/nicolai86/scaleway-sdk v1.10.2-0.20180628010248-798f60e20bb2/go.mod h1:TLb2Sg7HQcgGdloNxkrmtgDNR9uVYF3lfdFIN4Ro6Sk= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nlopes/slack v0.6.1-0.20191106133607-d06c2a2b3249/go.mod h1:JzQ9m3PMAqcpeCam7UaHSuBuupz7CmpjehYMayT6YOk= github.com/nrdcg/auroradns v1.0.0/go.mod h1:6JPXKzIRzZzMqtTDgueIhTi6rFf1QvYE/HzqidhOhjw= @@ -631,10 +735,12 @@ github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo= github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= @@ -648,6 +754,7 @@ github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= @@ -656,12 +763,16 @@ github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnh github.com/oracle/oci-go-sdk v7.0.0+incompatible/go.mod h1:VQb79nF8Z2cwLkLS35ukwStZIg5F66tcBccjip/j888= github.com/ovh/go-ovh v0.0.0-20181109152953-ba5adb4cf014/go.mod h1:joRatxRJaZBsY3JAOEMcoOp05CnZzsx4scTxi95DHyQ= github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c/go.mod h1:X07ZCGwUbLaax7L0S3Tw4hpejzu63ZrrQiUe6W0hcy0= +github.com/packethost/packngo v0.1.1-0.20180711074735-b9cb5096f54c h1:vwpFWvAO8DeIZfFeqASzZfsxuWPno9ncAebBEP0N3uE= github.com/packethost/packngo v0.1.1-0.20180711074735-b9cb5096f54c/go.mod h1:otzZQXgoO96RTzDB/Hycg0qZcXZsWJGJRSXbmEIJ+4M= github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= +github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= @@ -669,6 +780,7 @@ github.com/philhofer/fwd v1.0.0 h1:UbZqGr5Y38ApvM/V/jEljVxwocdweyH+vmYvRPBnbqQ= github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pierrec/lz4 v2.2.6+incompatible h1:6aCX4/YZ9v8q69hTyiR7dNLnTA3fgtKHVVW5BCd5Znw= github.com/pierrec/lz4 v2.2.6+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -676,9 +788,12 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/posener/complete v1.2.3 h1:NP0eAhjcjImqslEwo/1hq7gpajME0fTLTezBKDqfXqo= github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= +github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 h1:J9b7z+QKAmPf4YLrFg6oQUotqHQeUNWwkvo7jZp1GLU= github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= @@ -688,11 +803,13 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5Fsn github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +github.com/prometheus/client_golang v1.8.0 h1:zvJNkoCFAnYFNC24FV8nW4JdRJ3GIFcLbg65lL/JDcw= github.com/prometheus/client_golang v1.8.0/go.mod h1:O9VU6huf47PktckDQfMTX0Y8tY0/7TSWwj+ITvv0TnM= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= @@ -702,6 +819,7 @@ github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8 github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= +github.com/prometheus/common v0.14.0 h1:RHRyE8UocrbjU+6UvRzwi6HjiDfxrrBU91TtbKzkGp4= github.com/prometheus/common v0.14.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= @@ -712,11 +830,13 @@ github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDa github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.2.0 h1:wH4vA7pcjKuZzjF7lM8awk4fnuJO6idemZXoKnULUx4= github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/rainycape/memcache v0.0.0-20150622160815-1031fa0ce2f2/go.mod h1:7tZKcyumwBO6qip7RNQ5r77yrssm9bfCowcLEBcU5IA= github.com/rboyer/safeio v0.2.1/go.mod h1:Cq/cEPK+YXFn622lsQ0K4KsPZSPtaptHHEldsy7Fmig= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/renier/xmlrpc v0.0.0-20170708154548-ce4a1a486c03 h1:Wdi9nwnhFNAlseAOekn6B5G/+GMtks9UKbvRU/CMM/o= github.com/renier/xmlrpc v0.0.0-20170708154548-ce4a1a486c03/go.mod h1:gRAiPF5C5Nd0eyyRdqIu9qTiFSoZzpTq727b5B8fkkU= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -725,6 +845,7 @@ github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk= github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= github.com/sacloud/libsacloud v1.26.1/go.mod h1:79ZwATmHLIFZIMd7sxA3LwzVy/B77uj3LDoToVTxDoQ= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= @@ -733,9 +854,12 @@ github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b h1:gQZ0qzfKHQIybL github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/sean-/conswriter v0.0.0-20180208195008-f5ae3917a627/go.mod h1:7zjs06qF79/FKAJpBvFx3P8Ww4UTIMAe+lpNXDHziac= github.com/sean-/pager v0.0.0-20180208200047-666be9bf53b5/go.mod h1:BeybITEsBEg6qbIiqJ6/Bqeq25bCLbL7YFmpaFfJDuM= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/shirou/gopsutil v0.0.0-20181107111621-48177ef5f880 h1:1Ge4j/3uB2rxzPWD3TC+daeCw+w91z8UCUL/7WH5gn8= github.com/shirou/gopsutil v0.0.0-20181107111621-48177ef5f880/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4 h1:udFKJ0aHUL60LboW/A+DfgoHVedieIzIXE8uylPue0U= github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= @@ -743,56 +867,75 @@ github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjM github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/skratchdot/open-golang v0.0.0-20160302144031-75fb7ed4208c/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/softlayer/softlayer-go v0.0.0-20180806151055-260589d94c7d h1:bVQRCxQvfjNUeRqaY/uT0tFuvuFY0ulgnczuR684Xic= github.com/softlayer/softlayer-go v0.0.0-20180806151055-260589d94c7d/go.mod h1:Cw4GTlQccdRGSEf6KiMju767x0NEHE0YIVPJSaXjlsw= +github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.1/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= +github.com/spf13/viper v1.7.1 h1:pM5oEahlgWv/WnHXpgbKz7iLIxRf65tye2Ci+XFK5sk= github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= +github.com/tebeka/strftime v0.1.3 h1:5HQXOqWKYRFfNyBMNVc9z5+QzuBtIXy03psIhtdJYto= github.com/tebeka/strftime v0.1.3/go.mod h1:7wJm3dZlpr4l/oVK0t1HYIc4rMzQ2XJlOMIUJUJH6XQ= github.com/technoweenie/multipartstreamer v1.0.1/go.mod h1:jNVxdtShOxzAsukZwTSw6MDx5eUJoiEBsSvzDU9uzog= +github.com/tencentcloud/tencentcloud-sdk-go v3.0.83+incompatible h1:8uRvJleFpqLsO77WaAh2UrasMOzd8MxXrNj20e7El+Q= github.com/tencentcloud/tencentcloud-sdk-go v3.0.83+incompatible/go.mod h1:0PfYow01SHPMhKY31xa+EFz2RStxIqj6JFAJS+IkCi4= github.com/tent/http-link-go v0.0.0-20130702225549-ac974c61c2f9/go.mod h1:RHkNRtSLfOK7qBTHaeSX1D6BNpI3qw7NTxsmNr4RvN8= +github.com/tevid/gohamcrest v1.1.1 h1:ou+xSqlIw1xfGTg1uq1nif/htZ2S3EzRqLm2BP+tYU0= github.com/tevid/gohamcrest v1.1.1/go.mod h1:3UvtWlqm8j5JbwYZh80D/PVBt0mJ1eJiYgZMibh0H/k= github.com/timewasted/linode v0.0.0-20160829202747-37e84520dcf7/go.mod h1:imsgLplxEC/etjIhdr3dNzV3JeT27LbVu5pYWm0JCBY= github.com/tinylib/msgp v1.1.0 h1:9fQd+ICuRIu/ue4vxJZu6/LzxN0HwMds2nq/0cFvxHU= github.com/tinylib/msgp v1.1.0/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tmc/grpc-websocket-proxy v0.0.0-20200122045848-3419fae592fc h1:yUaosFVTJwnltaHbSNC3i82I92quFs+OFPRl8kNMVwo= github.com/tmc/grpc-websocket-proxy v0.0.0-20200122045848-3419fae592fc/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/toolkits/concurrent v0.0.0-20150624120057-a4371d70e3e3 h1:kF/7m/ZU+0D4Jj5eZ41Zm3IH/J8OElK1Qtd7tVKAwLk= github.com/toolkits/concurrent v0.0.0-20150624120057-a4371d70e3e3/go.mod h1:QDlpd3qS71vYtakd2hmdpqhJ9nwv6mD6A30bQ1BPBFE= github.com/transip/gotransip v0.0.0-20190812104329-6d8d9179b66f/go.mod h1:i0f4R4o2HM0m3DZYQWsj6/MEowD57VzoH0v3d7igeFY= +github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926 h1:G3dpKMzFDjgEh2q1Z7zUUtKa8ViPtH+ocF0bE0g00O8= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/uber-go/atomic v1.3.2/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= @@ -805,27 +948,33 @@ github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtX github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= github.com/valyala/fasttemplate v1.1.0/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= +github.com/vmware/govmomi v0.18.0 h1:f7QxSmP7meCtoAmiKZogvVbLInT+CZx6Px6K5rYsJZo= github.com/vmware/govmomi v0.18.0/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU= github.com/vultr/govultr v0.1.4/go.mod h1:9H008Uxr/C4vFNGLqKx232C206GL0PBHzOP0809bGNA= +github.com/willf/bitset v1.1.10 h1:NotGKqX0KwQ72NUzqrjZq5ipPNDQex9lo3WpaS8L2sc= github.com/willf/bitset v1.1.10/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs= github.com/xeipuuv/gojsonschema v1.1.0/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/zouyx/agollo/v3 v3.4.5 h1:7YCxzY9ZYaH9TuVUBvmI6Tk0mwMggikah+cfbYogcHQ= github.com/zouyx/agollo/v3 v3.4.5/go.mod h1:LJr3kDmm23QSW+F1Ol4TMHDa7HvJvscMdVxJ2IpUTVc= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.4 h1:hi1bXHMVrlQh6WwxAy+qZCV/SYIlqo+Ushwdpa4tAKg= go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2 h1:75k/FF0Q2YM8QYo07VPddOLBslDt1MZOdEslOHvmzAs= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -838,6 +987,7 @@ go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+ go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/ratelimit v0.0.0-20180316092928-c15da0234277/go.mod h1:2X8KaoNd1J0lZV+PxJk/5+DGbO/tpwLR1m++a7FnB/Y= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= @@ -867,6 +1017,7 @@ golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -884,6 +1035,7 @@ golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= @@ -891,6 +1043,7 @@ golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKG golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180611182652-db08ff08e862/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -924,9 +1077,11 @@ golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -934,6 +1089,7 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208 h1:qwRHBd0NqMbJxfbotnDhm2ByMI1Shq4Y6oRJo21SGJA= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180622082034-63fc586f45fe/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -985,16 +1141,19 @@ golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211 h1:9UQO31fZ+0aKQOFldThf7BKPMJTiBfWycGh/u3UoO88= golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190921001708-c4c64cad1fd0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1027,10 +1186,12 @@ golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200426102838-f3a5411a4c3b/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200928182047-19e03678916f h1:VwGa2Wf+rHGIxvsssCkUNIyFv8jQY0VCBCNWtikoWq0= golang.org/x/tools v0.0.0-20200928182047-19e03678916f/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= @@ -1038,12 +1199,14 @@ google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0 h1:uMf5uLi4eQMRrMKhCplNik4U4H8Z6C1br3zOtAa/aDE= google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= @@ -1057,6 +1220,7 @@ google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98 google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1 h1:aQktFqmDE2yjveXJlVIfslDFmFnUXSqG0i6KRcJAeMc= google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= @@ -1070,6 +1234,7 @@ google.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.26.0 h1:2dTRdpdFEEhJYQD8EMLB61nnrzSCTbG38PhqdhvOltg= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -1077,6 +1242,7 @@ google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= @@ -1084,25 +1250,32 @@ gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUy gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ= gopkg.in/h2non/gock.v1 v1.0.15/go.mod h1:sX4zAkdYX1TRGJ2JY156cFspQn4yRWn6p9EMdODlynE= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.44.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ns1/ns1-go.v2 v2.0.0-20190730140822-b51389932cbc/go.mod h1:VV+3haRsgDiVLxyifmMBrBIuCWFBPYKbRssXB9z67Hw= gopkg.in/resty.v1 v1.9.1/go.mod h1:vo52Hzryw9PnPHcJfPsBiFW62XhNx5OczbV9y+IMpgc= +gopkg.in/resty.v1 v1.12.0 h1:CuXP0Pjfw9rOuY6EP+UvtNvt5DSqHpIxILZKT/quCZI= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/square/go-jose.v2 v2.4.1 h1:H0TmLt7/KmzlrDOpa1F+zr0Tk90PbJYBfsVUmRLrf9Y= gopkg.in/square/go-jose.v2 v2.4.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/telegram-bot-api.v4 v4.6.4/go.mod h1:5DpGO5dbumb40px+dXcwCpcjmeHNYLpk0bp3XRNvWDM= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= @@ -1114,6 +1287,7 @@ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -1121,20 +1295,28 @@ honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= istio.io/gogo-genproto v0.0.0-20190124151557-6d926a6e6feb/go.mod h1:eIDJ6jNk/IeJz6ODSksHl5Aiczy5JUq6vFhJWI5OtiI= +k8s.io/api v0.16.9 h1:3vCx0WX9qcg1Hv4aQ/G1tiIKectGVuimvPVTJU4VOCA= k8s.io/api v0.16.9/go.mod h1:Y7dZNHs1Xy0mSwSlzL9QShi6qkljnN41yR8oWCRTDe8= +k8s.io/apimachinery v0.16.9 h1:ESUZ4hMBUKF2kn2HBFL5zM/wQv4j/0uRbR7AjgqGJ4o= k8s.io/apimachinery v0.16.9/go.mod h1:Xk2vD2TRRpuWYLQNM6lT9R7DSFZUYG03SarNkbGrnKE= +k8s.io/client-go v0.16.9 h1:6Eh4lMDxFtDzBkqid1AOL3bQ/pPYrulx8l23DXw4mRU= k8s.io/client-go v0.16.9/go.mod h1:ThjPlh7Kx+XoBFOCt775vx5J7atwY7F/zaFzTco5gL0= k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= k8s.io/kube-openapi v0.0.0-20190816220812-743ec37842bf/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E= +k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a h1:UcxjrRMyNx/i/y8G7kPvLyy7rfbeuf1PYyBf973pgyU= k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E= k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= +k8s.io/utils v0.0.0-20190801114015-581e00157fb1 h1:+ySTxfHnfzZb9ys375PXNlLhkJPLKgHajBU0N62BDvE= k8s.io/utils v0.0.0-20190801114015-581e00157fb1/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= +sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= From 0b7206b9a30fbed0cb12ae75769e3aa6cd35acd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=BF=97=E4=BF=A1?= Date: Sun, 27 Dec 2020 17:07:58 +0800 Subject: [PATCH 12/39] fix: go mod tidy --- go.sum | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/go.sum b/go.sum index 1c1656d64a..fdf037852f 100644 --- a/go.sum +++ b/go.sum @@ -236,6 +236,7 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9 github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= +github.com/go-ole/go-ole v1.2.1 h1:2lOsA72HgjxAuMlKpFiCbHTvu44PIVkZ5hqm3RSdI/E= github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= @@ -254,6 +255,7 @@ github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFG github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d h1:3PaI8p3seN09VjbTYC/QWlUZdZ1qS1zGjy7LH2Wt07I= github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= @@ -311,6 +313,7 @@ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5m github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/gnostic v0.2.0 h1:l6N3VoaVzTncYYW+9yOz2LJJammFZGBO13sqgEhpy9g= github.com/googleapis/gnostic v0.2.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/gophercloud/gophercloud v0.1.0 h1:P/nh25+rzXouhytV2pUHBb65fnds26Ghl8/391+sT5o= github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= @@ -442,6 +445,7 @@ github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28= github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= @@ -487,6 +491,7 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/lestrrat/go-envload v0.0.0-20180220120943-6ed08b54a570 h1:0iQektZGS248WXmGIYOwRXSQhD4qn3icjMpuxwO7qlo= github.com/lestrrat/go-envload v0.0.0-20180220120943-6ed08b54a570/go.mod h1:BLt8L9ld7wVsvEWQbuLrUZnCMnUmLZ+CGDzKtclrTlE= @@ -497,6 +502,7 @@ github.com/lestrrat/go-strftime v0.0.0-20180220042222-ba3bf9c1d042/go.mod h1:TPp github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= +github.com/linode/linodego v0.7.1 h1:4WZmMpSA2NRwlPZcc0+4Gyn7rr99Evk9bnr0B3gXRKE= github.com/linode/linodego v0.7.1/go.mod h1:ga11n3ivecUrPCHN0rANxKmfWBJVkOXfLMZinAbj2sY= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= @@ -521,7 +527,7 @@ github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzp github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/miekg/dns v1.1.15/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/miekg/dns v1.1.26 h1:gPxPSwALAeHJSjarOs00QjVdV9QoBvc1D2ujQUr5BzU= github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/cli v1.1.0 h1:tEElEatulEHDeedTxwckzyYMA5c86fbmNIUL1hBIiTg= @@ -755,6 +761,7 @@ github.com/tevid/gohamcrest v1.1.1/go.mod h1:3UvtWlqm8j5JbwYZh80D/PVBt0mJ1eJiYgZ github.com/tinylib/msgp v1.1.0 h1:9fQd+ICuRIu/ue4vxJZu6/LzxN0HwMds2nq/0cFvxHU= github.com/tinylib/msgp v1.1.0/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc/wtumK+WB441p7ynQJzVuNRJiqddSIE3IlSEQ= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/toolkits/concurrent v0.0.0-20150624120057-a4371d70e3e3 h1:kF/7m/ZU+0D4Jj5eZ41Zm3IH/J8OElK1Qtd7tVKAwLk= github.com/toolkits/concurrent v0.0.0-20150624120057-a4371d70e3e3/go.mod h1:QDlpd3qS71vYtakd2hmdpqhJ9nwv6mD6A30bQ1BPBFE= @@ -974,6 +981,7 @@ google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEt google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0 h1:Q3Ui3V3/CVinFWFiW39Iw0kMuVrRzYX0wN6OPFp0lTA= google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -992,6 +1000,7 @@ google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dT google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a h1:Ob5/580gVHBJZgXnff1cZDbG+xLtMVE5mDRTe+nIsX4= google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= @@ -1019,6 +1028,7 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= From 74385992bddcef2fd1608eacd39f97420691d78f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=BF=97=E4=BF=A1?= Date: Mon, 28 Dec 2020 14:43:05 +0800 Subject: [PATCH 13/39] fix: change test file --- cluster/cluster_impl/failback_cluster_test.go | 7 +++++++ cluster/cluster_impl/failfast_cluster_test.go | 3 +++ cluster/cluster_impl/failsafe_cluster_test.go | 4 ++++ 3 files changed, 14 insertions(+) diff --git a/cluster/cluster_impl/failback_cluster_test.go b/cluster/cluster_impl/failback_cluster_test.go index 0edb81d428..d36e16e269 100644 --- a/cluster/cluster_impl/failback_cluster_test.go +++ b/cluster/cluster_impl/failback_cluster_test.go @@ -72,6 +72,8 @@ func TestFailbackSuceess(t *testing.T) { invoker.EXPECT().GetUrl().Return(failbackUrl).AnyTimes() + invoker.EXPECT().IsAvailable().Return(true) + mockResult := &protocol.RPCResult{Rest: rest{tried: 0, success: true}} invoker.EXPECT().Invoke(gomock.Any()).Return(mockResult) @@ -88,6 +90,7 @@ func TestFailbackRetryOneSuccess(t *testing.T) { clusterInvoker := registerFailback(invoker).(*failbackClusterInvoker) invoker.EXPECT().GetUrl().Return(failbackUrl).AnyTimes() + invoker.EXPECT().IsAvailable().Return(true) // failed at first mockFailedResult := &protocol.RPCResult{Err: perrors.New("error")} @@ -98,6 +101,7 @@ func TestFailbackRetryOneSuccess(t *testing.T) { wg.Add(1) now := time.Now() mockSuccResult := &protocol.RPCResult{Rest: rest{tried: 0, success: true}} + invoker.EXPECT().IsAvailable().Return(true) invoker.EXPECT().Invoke(gomock.Any()).DoAndReturn(func(protocol.Invocation) protocol.Result { delta := time.Since(now).Nanoseconds() / int64(time.Second) assert.True(t, delta >= 5) @@ -131,6 +135,7 @@ func TestFailbackRetryFailed(t *testing.T) { clusterInvoker := registerFailback(invoker).(*failbackClusterInvoker) invoker.EXPECT().GetUrl().Return(failbackUrl).AnyTimes() + invoker.EXPECT().IsAvailable().Return(true).AnyTimes() mockFailedResult := &protocol.RPCResult{Err: perrors.New("error")} invoker.EXPECT().Invoke(gomock.Any()).Return(mockFailedResult) @@ -177,6 +182,7 @@ func TestFailbackRetryFailed10Times(t *testing.T) { clusterInvoker := registerFailback(invoker).(*failbackClusterInvoker) clusterInvoker.maxRetries = 10 + invoker.EXPECT().IsAvailable().Return(true).AnyTimes() invoker.EXPECT().GetUrl().Return(failbackUrl).AnyTimes() // 10 task should failed firstly. @@ -220,6 +226,7 @@ func TestFailbackOutOfLimit(t *testing.T) { clusterInvoker.failbackTasks = 1 invoker.EXPECT().GetUrl().Return(failbackUrl).AnyTimes() + invoker.EXPECT().IsAvailable().Return(true).AnyTimes() mockFailedResult := &protocol.RPCResult{Err: perrors.New("error")} invoker.EXPECT().Invoke(gomock.Any()).Return(mockFailedResult).Times(11) diff --git a/cluster/cluster_impl/failfast_cluster_test.go b/cluster/cluster_impl/failfast_cluster_test.go index 77e8e9c5da..9ac06b8d4a 100644 --- a/cluster/cluster_impl/failfast_cluster_test.go +++ b/cluster/cluster_impl/failfast_cluster_test.go @@ -53,6 +53,7 @@ func registerFailfast(invoker *mock.MockInvoker) protocol.Invoker { invokers := []protocol.Invoker{} invokers = append(invokers, invoker) + invoker.EXPECT().IsAvailable().Return(true).AnyTimes() invoker.EXPECT().GetUrl().Return(failfastUrl) staticDir := directory.NewStaticDirectory(invokers) @@ -67,6 +68,7 @@ func TestFailfastInvokeSuccess(t *testing.T) { invoker := mock.NewMockInvoker(ctrl) clusterInvoker := registerFailfast(invoker) + invoker.EXPECT().IsAvailable().Return(true).AnyTimes() invoker.EXPECT().GetUrl().Return(failfastUrl).AnyTimes() mockResult := &protocol.RPCResult{Rest: rest{tried: 0, success: true}} @@ -87,6 +89,7 @@ func TestFailfastInvokeFail(t *testing.T) { invoker := mock.NewMockInvoker(ctrl) clusterInvoker := registerFailfast(invoker) + invoker.EXPECT().IsAvailable().Return(true).AnyTimes() invoker.EXPECT().GetUrl().Return(failfastUrl).AnyTimes() mockResult := &protocol.RPCResult{Err: perrors.New("error")} diff --git a/cluster/cluster_impl/failsafe_cluster_test.go b/cluster/cluster_impl/failsafe_cluster_test.go index d9a716e1ae..5e208bddde 100644 --- a/cluster/cluster_impl/failsafe_cluster_test.go +++ b/cluster/cluster_impl/failsafe_cluster_test.go @@ -52,6 +52,7 @@ func registerFailsafe(invoker *mock.MockInvoker) protocol.Invoker { invokers := []protocol.Invoker{} invokers = append(invokers, invoker) + invoker.EXPECT().IsAvailable().Return(true).AnyTimes() invoker.EXPECT().GetUrl().Return(failbackUrl) @@ -67,6 +68,8 @@ func TestFailSafeInvokeSuccess(t *testing.T) { invoker := mock.NewMockInvoker(ctrl) clusterInvoker := registerFailsafe(invoker) + invoker.EXPECT().IsAvailable().Return(true).AnyTimes() + invoker.EXPECT().GetUrl().Return(failsafeUrl).AnyTimes() mockResult := &protocol.RPCResult{Rest: rest{tried: 0, success: true}} @@ -85,6 +88,7 @@ func TestFailSafeInvokeFail(t *testing.T) { invoker := mock.NewMockInvoker(ctrl) clusterInvoker := registerFailsafe(invoker) + invoker.EXPECT().IsAvailable().Return(true).AnyTimes() invoker.EXPECT().GetUrl().Return(failsafeUrl).AnyTimes() From 7dfa6be2738f6ee80cb92a6df73337cbcee546ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=BF=97=E4=BF=A1?= Date: Mon, 28 Dec 2020 15:24:48 +0800 Subject: [PATCH 14/39] fix: add health check test file --- .../router/conncheck/conn_check_route_test.go | 26 +++++++++++++++---- protocol/rpc_status.go | 1 + 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/cluster/router/conncheck/conn_check_route_test.go b/cluster/router/conncheck/conn_check_route_test.go index 9c78fd3899..95b8d4a928 100644 --- a/cluster/router/conncheck/conn_check_route_test.go +++ b/cluster/router/conncheck/conn_check_route_test.go @@ -19,8 +19,9 @@ package conncheck import ( "fmt" + "github.com/apache/dubbo-go/protocol/mock" + "github.com/golang/mock/gomock" "testing" - "time" ) import ( @@ -74,12 +75,27 @@ func TestConnCheckRouterRoute(t *testing.T) { // now invoker3 invoker1 is healthy assert.True(t, len(res.ToArray()) == 2) +} + +func TestRecovery(t *testing.T) { // check recover + + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + invoker1 := mock.NewMockInvoker(ctrl) + invoker2 := mock.NewMockInvoker(ctrl) + + invoker1.EXPECT().GetUrl().Return(&common.URL{Path: "path1"}).AnyTimes() + invoker2.EXPECT().GetUrl().Return(&common.URL{Path: "path2"}).AnyTimes() + invoker1.EXPECT().IsAvailable().Return(true).AnyTimes() + invoker2.EXPECT().IsAvailable().Return(true).AnyTimes() + + protocol.SetInvokerUnhealthyStatus(invoker1) + protocol.SetInvokerUnhealthyStatus(invoker2) + assert.Equal(t, len(protocol.GetBlackListInvokers(16)), 2) protocol.TryRefreshBlackList() - time.Sleep(time.Second) - res = hcr.Route(utils.ToBitmap(invokers), setUpAddrCache(hcr.(*ConnCheckRouter), invokers), consumerURL, inv) - // now all invokers are healthy - assert.True(t, len(res.ToArray()) == 3) + assert.Equal(t, len(protocol.GetBlackListInvokers(16)), 0) } func setUpAddrCache(r router.Poolable, addrs []protocol.Invoker) router.Cache { diff --git a/protocol/rpc_status.go b/protocol/rpc_status.go index 1e0b311e27..72ad34460d 100644 --- a/protocol/rpc_status.go +++ b/protocol/rpc_status.go @@ -241,6 +241,7 @@ func TryRefreshBlackList() { for i := 0; i < 3; i++ { wg.Add(1) go func(ivks []Invoker, i int) { + defer wg.Done() for j, _ := range ivks { if j%3-i == 0 { if ivks[j].(Invoker).IsAvailable() { From 8e92b2d347c20676ba226b4d8affe452023ece52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=BF=97=E4=BF=A1?= Date: Mon, 28 Dec 2020 15:46:09 +0800 Subject: [PATCH 15/39] fix: change from trigger to event driven refresh cache --- cluster/router/chain/chain.go | 35 ++++++++--------------------------- common/constant/key.go | 2 ++ 2 files changed, 10 insertions(+), 27 deletions(-) diff --git a/cluster/router/chain/chain.go b/cluster/router/chain/chain.go index 8b98acb582..d85f916661 100644 --- a/cluster/router/chain/chain.go +++ b/cluster/router/chain/chain.go @@ -65,8 +65,6 @@ type RouterChain struct { notify chan struct{} // Address cache cache atomic.Value - // init - init sync.Once } // Route Loop routers in RouterChain and call Route method to determine the target invokers list. @@ -113,35 +111,18 @@ func (c *RouterChain) SetInvokers(invokers []protocol.Invoker) { c.invokers = invokers c.mutex.Unlock() - // it should trigger init router for first call - c.init.Do(func() { - go func() { - c.notify <- struct{}{} - }() - }) - - c.count++ - now := time.Now() - if c.count >= countThreshold && now.Sub(c.last) >= timeThreshold { - c.last = now - c.count = 0 - go func() { - c.notify <- struct{}{} - }() - } + // it should trigger cache to refresh + go func() { + c.notify <- struct{}{} + }() } -// loop listens on events to update the address cache when it's necessary, either when it receives notification -// from address update, or when timeInterval exceeds. +// loop listens on events to update the address cache when it receives notification +// from address update, func (c *RouterChain) loop() { - ticker := time.NewTicker(timeInterval) for { - select { - case <-ticker.C: - c.buildCache() - case <-c.notify: - c.buildCache() - } + <-c.notify + c.buildCache() } } diff --git a/common/constant/key.go b/common/constant/key.go index 400a03f9f8..4376f742e0 100644 --- a/common/constant/key.go +++ b/common/constant/key.go @@ -299,6 +299,8 @@ const ( HEALTH_CHECKER = "health.checker" // The name of the default implementation of HealthChecker DEFAULT_HEALTH_CHECKER = "default" + // The name of the default implementation of C + DEFAULT_CONN_CHECKER = "default" // The key of outstanding-request-limit\ OUTSTANDING_REQUEST_COUNT_LIMIT_KEY = "outstanding.request.limit" // The key of successive-failed-request's threshold From f46696651c7e1db46ead08779afb608c295bed28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=BF=97=E4=BF=A1?= Date: Tue, 29 Dec 2020 14:50:44 +0800 Subject: [PATCH 16/39] ticker refresh chain cache only when needed --- cluster/router/chain/chain.go | 12 +++++++++--- protocol/rpc_status.go | 22 ++++++++++++++++++---- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/cluster/router/chain/chain.go b/cluster/router/chain/chain.go index d85f916661..fc54aec8ba 100644 --- a/cluster/router/chain/chain.go +++ b/cluster/router/chain/chain.go @@ -111,7 +111,6 @@ func (c *RouterChain) SetInvokers(invokers []protocol.Invoker) { c.invokers = invokers c.mutex.Unlock() - // it should trigger cache to refresh go func() { c.notify <- struct{}{} }() @@ -120,9 +119,16 @@ func (c *RouterChain) SetInvokers(invokers []protocol.Invoker) { // loop listens on events to update the address cache when it receives notification // from address update, func (c *RouterChain) loop() { + ticker := time.NewTicker(timeInterval) for { - <-c.notify - c.buildCache() + select { + case <-ticker.C: + if protocol.GetAndRefreshState() { + c.buildCache() + } + case <-c.notify: + c.buildCache() + } } } diff --git a/protocol/rpc_status.go b/protocol/rpc_status.go index 72ad34460d..85a40f71a3 100644 --- a/protocol/rpc_status.go +++ b/protocol/rpc_status.go @@ -30,12 +30,17 @@ import ( ) var ( - methodStatistics sync.Map // url -> { methodName : RPCStatus} - serviceStatistic sync.Map // url -> RPCStatus - invokerBlackList sync.Map // store unhealthy url blackList - blackListRefreshing int32 // store if the refresing method is processing + methodStatistics sync.Map // url -> { methodName : RPCStatus} + serviceStatistic sync.Map // url -> RPCStatus + invokerBlackList sync.Map // store unhealthy url blackList + blackListCacheDirty atomic.Value // store if the cache in chain is not refreshed by blacklist + blackListRefreshing int32 // store if the refresing method is processing ) +func init() { + blackListCacheDirty.Store(false) +} + // RPCStatus is URL statistics. type RPCStatus struct { active int32 @@ -201,11 +206,13 @@ func GetInvokerHealthyStatus(invoker Invoker) bool { // SetInvokerUnhealthyStatus add target invoker to black list func SetInvokerUnhealthyStatus(invoker Invoker) { invokerBlackList.Store(invoker.GetUrl().Key(), invoker) + blackListCacheDirty.Store(true) } // RemoveInvokerUnhealthyStatus remove unhealthy status of target invoker from blacklist func RemoveInvokerUnhealthyStatus(invoker Invoker) { invokerBlackList.Delete(invoker.GetUrl().Key()) + blackListCacheDirty.Store(true) } // GetBlackListInvokers get at most size of blockSize invokers from black list @@ -224,6 +231,13 @@ func GetBlackListInvokers(blockSize int) []Invoker { // RemoveUrlKeyUnhealthyStatus called when event of provider unregister, delete from black list func RemoveUrlKeyUnhealthyStatus(key string) { invokerBlackList.Delete(key) + blackListCacheDirty.Store(true) +} + +func GetAndRefreshState() bool { + state := blackListCacheDirty.Load() + blackListCacheDirty.Store(false) + return state.(bool) } // TryRefreshBlackList start 3 gr to check at most block=16 invokers in black list From c822cfab41cf16eed5717220a05e1251ce567265 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=BF=97=E4=BF=A1?= Date: Tue, 29 Dec 2020 14:59:49 +0800 Subject: [PATCH 17/39] fix: go fmt file --- filter/filter_impl/sentinel_filter_test.go | 4 ++-- go.mod | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/filter/filter_impl/sentinel_filter_test.go b/filter/filter_impl/sentinel_filter_test.go index a1ca21ce6c..c6b6d4280f 100644 --- a/filter/filter_impl/sentinel_filter_test.go +++ b/filter/filter_impl/sentinel_filter_test.go @@ -50,11 +50,11 @@ func TestSentinelFilter_QPS(t *testing.T) { _, err = flow.LoadRules([]*flow.Rule{ { - Resource: interfaceResourceName, + Resource: interfaceResourceName, //MetricType: flow.QPS, TokenCalculateStrategy: flow.Direct, ControlBehavior: flow.Reject, - Threshold: 100, + Threshold: 100, RelationStrategy: flow.CurrentResource, }, }) diff --git a/go.mod b/go.mod index e822ab4cf3..68465d1946 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/apache/dubbo-go -go 1.15 +go 1.13 require ( github.com/NYTimes/gziphandler v1.1.1 // indirect From c1cc11389a31a3e4e1142926c8a5a88594fe6310 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=BF=97=E4=BF=A1?= Date: Wed, 30 Dec 2020 14:26:39 +0800 Subject: [PATCH 18/39] fix: add router change refresh cache logic --- cluster/router/chain/chain.go | 23 ++++++++++++++--------- protocol/rpc_status.go | 16 ++++++++++------ 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/cluster/router/chain/chain.go b/cluster/router/chain/chain.go index fc54aec8ba..d707173ccf 100644 --- a/cluster/router/chain/chain.go +++ b/cluster/router/chain/chain.go @@ -20,12 +20,12 @@ package chain import ( "sort" "sync" - "sync/atomic" "time" ) import ( perrors "github.com/pkg/errors" + "go.uber.org/atomic" ) import ( @@ -38,9 +38,7 @@ import ( ) const ( - timeInterval = 5 * time.Second - timeThreshold = 2 * time.Second - countThreshold = 5 + timeInterval = 5 * time.Second ) // RouterChain Router chain @@ -65,6 +63,8 @@ type RouterChain struct { notify chan struct{} // Address cache cache atomic.Value + // routerNeedsUpdate + routerNeedsUpdate atomic.Bool } // Route Loop routers in RouterChain and call Route method to determine the target invokers list. @@ -102,6 +102,7 @@ func (c *RouterChain) AddRouters(routers []router.PriorityRouter) { c.mutex.Lock() defer c.mutex.Unlock() c.routers = newRouters + c.routerNeedsUpdate.Store(true) } // SetInvokers receives updated invokers from registry center. If the times of notification exceeds countThreshold and @@ -123,8 +124,9 @@ func (c *RouterChain) loop() { for { select { case <-ticker.C: - if protocol.GetAndRefreshState() { + if protocol.GetAndRefreshState() || c.routerNeedsUpdate.Load() { c.buildCache() + c.routerNeedsUpdate.Store(false) } case <-c.notify: c.buildCache() @@ -237,11 +239,14 @@ func NewRouterChain(url *common.URL) (*RouterChain, error) { sortRouter(newRouters) + routerNeedsUpdateInit := atomic.Bool{} + routerNeedsUpdateInit.Store(false) chain := &RouterChain{ - builtinRouters: routers, - routers: newRouters, - last: time.Now(), - notify: make(chan struct{}), + builtinRouters: routers, + routers: newRouters, + last: time.Now(), + notify: make(chan struct{}), + routerNeedsUpdate: routerNeedsUpdateInit, } if url != nil { chain.url = url diff --git a/protocol/rpc_status.go b/protocol/rpc_status.go index 85a40f71a3..5f6225ba7c 100644 --- a/protocol/rpc_status.go +++ b/protocol/rpc_status.go @@ -23,6 +23,10 @@ import ( "time" ) +import ( + uberAtomic "go.uber.org/atomic" +) + import ( "github.com/apache/dubbo-go/common" "github.com/apache/dubbo-go/common/constant" @@ -30,11 +34,11 @@ import ( ) var ( - methodStatistics sync.Map // url -> { methodName : RPCStatus} - serviceStatistic sync.Map // url -> RPCStatus - invokerBlackList sync.Map // store unhealthy url blackList - blackListCacheDirty atomic.Value // store if the cache in chain is not refreshed by blacklist - blackListRefreshing int32 // store if the refresing method is processing + methodStatistics sync.Map // url -> { methodName : RPCStatus} + serviceStatistic sync.Map // url -> RPCStatus + invokerBlackList sync.Map // store unhealthy url blackList + blackListCacheDirty uberAtomic.Bool // store if the cache in chain is not refreshed by blacklist + blackListRefreshing int32 // store if the refresing method is processing ) func init() { @@ -237,7 +241,7 @@ func RemoveUrlKeyUnhealthyStatus(key string) { func GetAndRefreshState() bool { state := blackListCacheDirty.Load() blackListCacheDirty.Store(false) - return state.(bool) + return state } // TryRefreshBlackList start 3 gr to check at most block=16 invokers in black list From 482f9dc473b57bf6405036d07d5fe8341768d276 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=BF=97=E4=BF=A1?= Date: Thu, 31 Dec 2020 10:52:16 +0800 Subject: [PATCH 19/39] feat: router change event driven chain cache refresh --- cluster/directory/base_directory.go | 8 +-- cluster/router/chain.go | 2 + cluster/router/chain/chain.go | 28 +++++---- cluster/router/chain/chain_test.go | 3 +- cluster/router/condition/app_router.go | 5 +- cluster/router/condition/app_router_test.go | 9 ++- cluster/router/condition/factory.go | 8 +-- cluster/router/condition/factory_test.go | 62 +++++++++++-------- cluster/router/condition/listenable_router.go | 5 +- cluster/router/condition/router.go | 4 +- cluster/router/condition/router_test.go | 11 ++-- cluster/router/conncheck/conn_check_route.go | 6 +- .../router/conncheck/conn_check_route_test.go | 3 +- cluster/router/conncheck/factory.go | 4 +- cluster/router/healthcheck/factory.go | 4 +- .../router/healthcheck/health_check_route.go | 4 +- .../healthcheck/health_check_route_test.go | 10 +-- cluster/router/router.go | 2 +- cluster/router/tag/factory.go | 4 +- cluster/router/tag/factory_test.go | 3 +- cluster/router/tag/file.go | 4 +- cluster/router/tag/tag_router.go | 5 +- cluster/router/tag/tag_router_test.go | 24 +++++-- 23 files changed, 135 insertions(+), 83 deletions(-) diff --git a/cluster/directory/base_directory.go b/cluster/directory/base_directory.go index d1025a152b..309cd4429c 100644 --- a/cluster/directory/base_directory.go +++ b/cluster/directory/base_directory.go @@ -82,6 +82,8 @@ func (dir *BaseDirectory) SetRouters(urls []*common.URL) { routers := make([]router.PriorityRouter, 0, len(urls)) + rc := dir.routerChain + for _, url := range urls { routerKey := url.GetParam(constant.ROUTER_KEY, "") @@ -94,7 +96,7 @@ func (dir *BaseDirectory) SetRouters(urls []*common.URL) { } } factory := extension.GetRouterFactory(url.Protocol) - r, err := factory.NewPriorityRouter(url) + r, err := factory.NewPriorityRouter(url, rc.GetNotifyChan()) if err != nil { logger.Errorf("Create router fail. router key: %s, url:%s, error: %+v", routerKey, url.Service(), err) return @@ -104,10 +106,8 @@ func (dir *BaseDirectory) SetRouters(urls []*common.URL) { logger.Infof("Init file condition router success, size: %v", len(routers)) dir.mutex.Lock() - rc := dir.routerChain - dir.mutex.Unlock() - rc.AddRouters(routers) + dir.mutex.Unlock() } func (dir *BaseDirectory) isProperRouter(url *common.URL) bool { diff --git a/cluster/router/chain.go b/cluster/router/chain.go index 3614d0a5a3..cb33cf927f 100644 --- a/cluster/router/chain.go +++ b/cluster/router/chain.go @@ -29,4 +29,6 @@ type Chain interface { SetInvokers([]protocol.Invoker) // AddRouters Add routers AddRouters([]PriorityRouter) + // GetNotifyChan get notify channel of this chain + GetNotifyChan() chan struct{} } diff --git a/cluster/router/chain/chain.go b/cluster/router/chain/chain.go index d707173ccf..57788975e7 100644 --- a/cluster/router/chain/chain.go +++ b/cluster/router/chain/chain.go @@ -63,8 +63,10 @@ type RouterChain struct { notify chan struct{} // Address cache cache atomic.Value - // routerNeedsUpdate - routerNeedsUpdate atomic.Bool +} + +func (c *RouterChain) GetNotifyChan() chan struct{} { + return c.notify } // Route Loop routers in RouterChain and call Route method to determine the target invokers list. @@ -102,7 +104,7 @@ func (c *RouterChain) AddRouters(routers []router.PriorityRouter) { c.mutex.Lock() defer c.mutex.Unlock() c.routers = newRouters - c.routerNeedsUpdate.Store(true) + c.notify <- struct{}{} } // SetInvokers receives updated invokers from registry center. If the times of notification exceeds countThreshold and @@ -124,9 +126,8 @@ func (c *RouterChain) loop() { for { select { case <-ticker.C: - if protocol.GetAndRefreshState() || c.routerNeedsUpdate.Load() { + if protocol.GetAndRefreshState() { c.buildCache() - c.routerNeedsUpdate.Store(false) } case <-c.notify: c.buildCache() @@ -224,9 +225,15 @@ func NewRouterChain(url *common.URL) (*RouterChain, error) { if len(routerFactories) == 0 { return nil, perrors.Errorf("No routerFactory exits , create one please") } + + chain := &RouterChain{ + last: time.Now(), + notify: make(chan struct{}), + } + routers := make([]router.PriorityRouter, 0, len(routerFactories)) for key, routerFactory := range routerFactories { - r, err := routerFactory().NewPriorityRouter(url) + r, err := routerFactory().NewPriorityRouter(url, chain.notify) if r == nil || err != nil { logger.Errorf("router chain build router fail! routerFactories key:%s error:%s", key, err.Error()) continue @@ -241,13 +248,8 @@ func NewRouterChain(url *common.URL) (*RouterChain, error) { routerNeedsUpdateInit := atomic.Bool{} routerNeedsUpdateInit.Store(false) - chain := &RouterChain{ - builtinRouters: routers, - routers: newRouters, - last: time.Now(), - notify: make(chan struct{}), - routerNeedsUpdate: routerNeedsUpdateInit, - } + chain.routers = newRouters + chain.builtinRouters = routers if url != nil { chain.url = url } diff --git a/cluster/router/chain/chain_test.go b/cluster/router/chain/chain_test.go index b21990b08c..f274d1b318 100644 --- a/cluster/router/chain/chain_test.go +++ b/cluster/router/chain/chain_test.go @@ -142,7 +142,8 @@ conditions: url := getConditionRouteUrl(applicationKey) assert.NotNil(t, url) factory := extension.GetRouterFactory(url.Protocol) - r, err := factory.NewPriorityRouter(url) + notify := make(chan struct{}) + r, err := factory.NewPriorityRouter(url, notify) assert.Nil(t, err) assert.NotNil(t, r) diff --git a/cluster/router/condition/app_router.go b/cluster/router/condition/app_router.go index 056e32851c..64b3914b87 100644 --- a/cluster/router/condition/app_router.go +++ b/cluster/router/condition/app_router.go @@ -34,14 +34,15 @@ const ( // AppRouter For listen application router with config center type AppRouter struct { listenableRouter + notify interface{} } // NewAppRouter Init AppRouter by url -func NewAppRouter(url *common.URL) (*AppRouter, error) { +func NewAppRouter(url *common.URL, notify chan struct{}) (*AppRouter, error) { if url == nil { return nil, perrors.Errorf("No route URL for create app router!") } - appRouter, err := newListenableRouter(url, url.GetParam(constant.APPLICATION_KEY, "")) + appRouter, err := newListenableRouter(url, url.GetParam(constant.APPLICATION_KEY, ""), notify) if err != nil { return nil, err } diff --git a/cluster/router/condition/app_router_test.go b/cluster/router/condition/app_router_test.go index 879abc5cc8..c47aaaf80b 100644 --- a/cluster/router/condition/app_router_test.go +++ b/cluster/router/condition/app_router_test.go @@ -78,7 +78,8 @@ conditions: assert.NotNil(t, configuration) appRouteURL := getAppRouteURL(routerKey) - appRouter, err := NewAppRouter(appRouteURL) + notify := make(chan struct{}) + appRouter, err := NewAppRouter(appRouteURL, notify) assert.Nil(t, err) assert.NotNil(t, appRouter) @@ -126,7 +127,8 @@ conditions: assert.NotNil(t, configuration) appRouteURL := getAppRouteURL(routerKey) - appRouter, err := NewAppRouter(appRouteURL) + notify := make(chan struct{}) + appRouter, err := NewAppRouter(appRouteURL, notify) assert.Nil(t, err) assert.NotNil(t, appRouter) @@ -165,7 +167,8 @@ conditions: assert.NotNil(t, configuration) appRouteURL := getAppRouteURL(routerKey) - appRouter, err := NewAppRouter(appRouteURL) + notify := make(chan struct{}) + appRouter, err := NewAppRouter(appRouteURL, notify) assert.Nil(t, err) assert.NotNil(t, appRouter) diff --git a/cluster/router/condition/factory.go b/cluster/router/condition/factory.go index f8d3e13010..2c1f03516a 100644 --- a/cluster/router/condition/factory.go +++ b/cluster/router/condition/factory.go @@ -37,8 +37,8 @@ func newConditionRouterFactory() router.PriorityRouterFactory { } // NewPriorityRouter creates ConditionRouterFactory by URL -func (c *ConditionRouterFactory) NewPriorityRouter(url *common.URL) (router.PriorityRouter, error) { - return NewConditionRouter(url) +func (c *ConditionRouterFactory) NewPriorityRouter(url *common.URL, notify chan struct{}) (router.PriorityRouter, error) { + return NewConditionRouter(url, notify) } // NewRouter Create FileRouterFactory by Content @@ -54,6 +54,6 @@ func newAppRouterFactory() router.PriorityRouterFactory { } // NewPriorityRouter creates AppRouterFactory by URL -func (c *AppRouterFactory) NewPriorityRouter(url *common.URL) (router.PriorityRouter, error) { - return NewAppRouter(url) +func (c *AppRouterFactory) NewPriorityRouter(url *common.URL, notify chan struct{}) (router.PriorityRouter, error) { + return NewAppRouter(url, notify) } diff --git a/cluster/router/condition/factory_test.go b/cluster/router/condition/factory_test.go index c916588eee..c8cc9c9761 100644 --- a/cluster/router/condition/factory_test.go +++ b/cluster/router/condition/factory_test.go @@ -132,37 +132,39 @@ func (bi *MockInvoker) Destroy() { func TestRoute_matchWhen(t *testing.T) { inv := &invocation.RPCInvocation{} rule := base64.URLEncoding.EncodeToString([]byte("=> host = 1.2.3.4")) - router, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule)) + notify := make(chan struct{}) + router, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule), notify) cUrl, _ := common.NewURL(fmt.Sprintf(factoryDubboFormat, factory1111Ip)) matchWhen := router.(*ConditionRouter).MatchWhen(cUrl, inv) assert.Equal(t, true, matchWhen) rule1 := base64.URLEncoding.EncodeToString([]byte("host = 2.2.2.2,1.1.1.1,3.3.3.3 => host = 1.2.3.4")) - router1, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule1)) + router1, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule1), notify) matchWhen1 := router1.(*ConditionRouter).MatchWhen(cUrl, inv) assert.Equal(t, true, matchWhen1) rule2 := base64.URLEncoding.EncodeToString([]byte("host = 2.2.2.2,1.1.1.1,3.3.3.3 & host !=1.1.1.1 => host = 1.2.3.4")) - router2, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule2)) + router2, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule2), notify) matchWhen2 := router2.(*ConditionRouter).MatchWhen(cUrl, inv) assert.Equal(t, false, matchWhen2) rule3 := base64.URLEncoding.EncodeToString([]byte("host !=4.4.4.4 & host = 2.2.2.2,1.1.1.1,3.3.3.3 => host = 1.2.3.4")) - router3, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule3)) + router3, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule3), notify) matchWhen3 := router3.(*ConditionRouter).MatchWhen(cUrl, inv) assert.Equal(t, true, matchWhen3) rule4 := base64.URLEncoding.EncodeToString([]byte("host !=4.4.4.* & host = 2.2.2.2,1.1.1.1,3.3.3.3 => host = 1.2.3.4")) - router4, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule4)) + router4, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule4), notify) matchWhen4 := router4.(*ConditionRouter).MatchWhen(cUrl, inv) assert.Equal(t, true, matchWhen4) rule5 := base64.URLEncoding.EncodeToString([]byte("host = 2.2.2.2,1.1.1.*,3.3.3.3 & host != 1.1.1.1 => host = 1.2.3.4")) - router5, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule5)) + router5, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule5), notify) matchWhen5 := router5.(*ConditionRouter).MatchWhen(cUrl, inv) assert.Equal(t, false, matchWhen5) rule6 := base64.URLEncoding.EncodeToString([]byte("host = 2.2.2.2,1.1.1.*,3.3.3.3 & host != 1.1.1.2 => host = 1.2.3.4")) - router6, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule6)) + router6, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule6), notify) matchWhen6 := router6.(*ConditionRouter).MatchWhen(cUrl, inv) assert.Equal(t, true, matchWhen6) } func TestRoute_matchFilter(t *testing.T) { + notify := make(chan struct{}) localIP := common.GetLocalIp() t.Logf("The local ip is %s", localIP) url1, _ := common.NewURL("dubbo://10.20.3.3:20880/com.foo.BarService?default.serialization=fastjson") @@ -175,12 +177,12 @@ func TestRoute_matchFilter(t *testing.T) { rule4 := base64.URLEncoding.EncodeToString([]byte("host = " + localIP + " => " + " host = 10.20.3.2,10.20.3.3,10.20.3.4")) rule5 := base64.URLEncoding.EncodeToString([]byte("host = " + localIP + " => " + " host != 10.20.3.3")) rule6 := base64.URLEncoding.EncodeToString([]byte("host = " + localIP + " => " + " serialization = fastjson")) - router1, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule1)) - router2, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule2)) - router3, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule3)) - router4, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule4)) - router5, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule5)) - router6, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule6)) + router1, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule1), notify) + router2, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule2), notify) + router3, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule3), notify) + router4, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule4), notify) + router5, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule5), notify) + router6, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule6), notify) cUrl, _ := common.NewURL(fmt.Sprintf(factoryConsumerFormat, localIP)) ret1 := router1.Route(utils.ToBitmap(invokers), setUpAddrCache(invokers), cUrl, &invocation.RPCInvocation{}) ret2 := router2.Route(utils.ToBitmap(invokers), setUpAddrCache(invokers), cUrl, &invocation.RPCInvocation{}) @@ -198,9 +200,10 @@ func TestRoute_matchFilter(t *testing.T) { } func TestRoute_methodRoute(t *testing.T) { + notify := make(chan struct{}) inv := invocation.NewRPCInvocationWithOptions(invocation.WithMethodName("getFoo"), invocation.WithParameterTypes([]reflect.Type{}), invocation.WithArguments([]interface{}{})) rule := base64.URLEncoding.EncodeToString([]byte("host !=4.4.4.* & host = 2.2.2.2,1.1.1.1,3.3.3.3 => host = 1.2.3.4")) - r, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule)) + r, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule), notify) url, _ := common.NewURL("consumer://1.1.1.1/com.foo.BarService?methods=setFoo,getFoo,findFoo") matchWhen := r.(*ConditionRouter).MatchWhen(url, inv) assert.Equal(t, true, matchWhen) @@ -209,42 +212,45 @@ func TestRoute_methodRoute(t *testing.T) { assert.Equal(t, true, matchWhen) url2, _ := common.NewURL(fmt.Sprintf(factoryConsumerMethodFormat, factory1111Ip)) rule2 := base64.URLEncoding.EncodeToString([]byte("methods=getFoo & host!=1.1.1.1 => host = 1.2.3.4")) - router2, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule2)) + router2, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule2), notify) matchWhen = router2.(*ConditionRouter).MatchWhen(url2, inv) assert.Equal(t, false, matchWhen) url3, _ := common.NewURL(fmt.Sprintf(factoryConsumerMethodFormat, factory1111Ip)) rule3 := base64.URLEncoding.EncodeToString([]byte("methods=getFoo & host=1.1.1.1 => host = 1.2.3.4")) - router3, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule3)) + router3, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule3), notify) matchWhen = router3.(*ConditionRouter).MatchWhen(url3, inv) assert.Equal(t, true, matchWhen) } func TestRoute_ReturnFalse(t *testing.T) { + notify := make(chan struct{}) url, _ := common.NewURL("") localIP := common.GetLocalIp() invokers := []protocol.Invoker{NewMockInvoker(url, 1), NewMockInvoker(url, 2), NewMockInvoker(url, 3)} inv := &invocation.RPCInvocation{} rule := base64.URLEncoding.EncodeToString([]byte("host = " + localIP + " => false")) curl, _ := common.NewURL(fmt.Sprintf(factoryConsumerFormat, localIP)) - r, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule)) + r, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule), notify) ret := r.Route(utils.ToBitmap(invokers), setUpAddrCache(invokers), curl, inv) assert.Equal(t, 0, len(ret.ToArray())) } func TestRoute_ReturnEmpty(t *testing.T) { + notify := make(chan struct{}) localIP := common.GetLocalIp() url, _ := common.NewURL("") invokers := []protocol.Invoker{NewMockInvoker(url, 1), NewMockInvoker(url, 2), NewMockInvoker(url, 3)} inv := &invocation.RPCInvocation{} rule := base64.URLEncoding.EncodeToString([]byte("host = " + localIP + " => ")) curl, _ := common.NewURL(fmt.Sprintf(factoryConsumerFormat, localIP)) - r, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule)) + r, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule), notify) ret := r.Route(utils.ToBitmap(invokers), setUpAddrCache(invokers), curl, inv) assert.Equal(t, 0, len(ret.ToArray())) } func TestRoute_ReturnAll(t *testing.T) { + notify := make(chan struct{}) localIP := common.GetLocalIp() urlString := "dubbo://" + localIP + "/com.foo.BarService" dubboURL, _ := common.NewURL(urlString) @@ -255,7 +261,7 @@ func TestRoute_ReturnAll(t *testing.T) { inv := &invocation.RPCInvocation{} rule := base64.URLEncoding.EncodeToString([]byte("host = " + localIP + " => " + " host = " + localIP)) curl, _ := common.NewURL(fmt.Sprintf(factoryConsumerFormat, localIP)) - r, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule)) + r, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule), notify) ret := r.Route(utils.ToBitmap(invokers), setUpAddrCache(invokers), curl, inv) assert.Equal(t, len(invokers), len(ret.ToArray())) } @@ -265,6 +271,7 @@ func TestRoute_HostFilter(t *testing.T) { url1, _ := common.NewURL(factory333URL) url2, _ := common.NewURL(fmt.Sprintf(factoryDubboFormat, localIP)) url3, _ := common.NewURL(fmt.Sprintf(factoryDubboFormat, localIP)) + notify := make(chan struct{}) invoker1 := NewMockInvoker(url1, 1) invoker2 := NewMockInvoker(url2, 2) invoker3 := NewMockInvoker(url3, 3) @@ -272,7 +279,7 @@ func TestRoute_HostFilter(t *testing.T) { inv := &invocation.RPCInvocation{} rule := base64.URLEncoding.EncodeToString([]byte("host = " + localIP + " => " + " host = " + localIP)) curl, _ := common.NewURL(fmt.Sprintf(factoryConsumerFormat, localIP)) - r, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule)) + r, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule), notify) ret := r.Route(utils.ToBitmap(invokers), setUpAddrCache(invokers), curl, inv) assert.Equal(t, 2, len(ret.ToArray())) assert.Equal(t, invoker2, invokers[ret.ToArray()[0]]) @@ -280,6 +287,7 @@ func TestRoute_HostFilter(t *testing.T) { } func TestRoute_Empty_HostFilter(t *testing.T) { + notify := make(chan struct{}) localIP := common.GetLocalIp() url1, _ := common.NewURL(factory333URL) url2, _ := common.NewURL(fmt.Sprintf(factoryDubboFormat, localIP)) @@ -291,7 +299,7 @@ func TestRoute_Empty_HostFilter(t *testing.T) { inv := &invocation.RPCInvocation{} rule := base64.URLEncoding.EncodeToString([]byte(" => " + " host = " + localIP)) curl, _ := common.NewURL(fmt.Sprintf(factoryConsumerFormat, localIP)) - r, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule)) + r, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule), notify) ret := r.Route(utils.ToBitmap(invokers), setUpAddrCache(invokers), curl, inv) assert.Equal(t, 2, len(ret.ToArray())) assert.Equal(t, invoker2, invokers[ret.ToArray()[0]]) @@ -299,6 +307,7 @@ func TestRoute_Empty_HostFilter(t *testing.T) { } func TestRoute_False_HostFilter(t *testing.T) { + notify := make(chan struct{}) localIP := common.GetLocalIp() url1, _ := common.NewURL(factory333URL) url2, _ := common.NewURL(fmt.Sprintf(factoryDubboFormat, localIP)) @@ -310,7 +319,7 @@ func TestRoute_False_HostFilter(t *testing.T) { inv := &invocation.RPCInvocation{} rule := base64.URLEncoding.EncodeToString([]byte("true => " + " host = " + localIP)) curl, _ := common.NewURL(fmt.Sprintf(factoryConsumerFormat, localIP)) - r, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule)) + r, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule), notify) ret := r.Route(utils.ToBitmap(invokers), setUpAddrCache(invokers), curl, inv) assert.Equal(t, 2, len(ret.ToArray())) assert.Equal(t, invoker2, invokers[ret.ToArray()[0]]) @@ -318,6 +327,7 @@ func TestRoute_False_HostFilter(t *testing.T) { } func TestRoute_Placeholder(t *testing.T) { + notify := make(chan struct{}) localIP := common.GetLocalIp() url1, _ := common.NewURL(factory333URL) url2, _ := common.NewURL(fmt.Sprintf(factoryDubboFormat, localIP)) @@ -329,7 +339,7 @@ func TestRoute_Placeholder(t *testing.T) { inv := &invocation.RPCInvocation{} rule := base64.URLEncoding.EncodeToString([]byte("host = " + localIP + " => " + " host = $host")) curl, _ := common.NewURL(fmt.Sprintf(factoryConsumerFormat, localIP)) - r, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule)) + r, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule), notify) ret := r.Route(utils.ToBitmap(invokers), setUpAddrCache(invokers), curl, inv) assert.Equal(t, 2, len(ret.ToArray())) assert.Equal(t, invoker2, invokers[ret.ToArray()[0]]) @@ -337,6 +347,7 @@ func TestRoute_Placeholder(t *testing.T) { } func TestRoute_NoForce(t *testing.T) { + notify := make(chan struct{}) localIP := common.GetLocalIp() url1, _ := common.NewURL(factory333URL) url2, _ := common.NewURL(fmt.Sprintf(factoryDubboFormat, localIP)) @@ -348,12 +359,13 @@ func TestRoute_NoForce(t *testing.T) { inv := &invocation.RPCInvocation{} rule := base64.URLEncoding.EncodeToString([]byte(fmt.Sprintf(factoryHostIp1234Format, localIP))) curl, _ := common.NewURL(fmt.Sprintf(factoryConsumerFormat, localIP)) - r, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrlWithNoForce(rule)) + r, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrlWithNoForce(rule), notify) ret := r.Route(utils.ToBitmap(invokers), setUpAddrCache(invokers), curl, inv) assert.Equal(t, len(invokers), len(ret.ToArray())) } func TestRoute_Force(t *testing.T) { + notify := make(chan struct{}) localIP := common.GetLocalIp() url1, _ := common.NewURL(factory333URL) url2, _ := common.NewURL(fmt.Sprintf(factoryDubboFormat, localIP)) @@ -365,7 +377,7 @@ func TestRoute_Force(t *testing.T) { inv := &invocation.RPCInvocation{} rule := base64.URLEncoding.EncodeToString([]byte(fmt.Sprintf(factoryHostIp1234Format, localIP))) curl, _ := common.NewURL(fmt.Sprintf(factoryConsumerFormat, localIP)) - r, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrlWithForce(rule, "true")) + r, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrlWithForce(rule, "true"), notify) fileredInvokers := r.Route(utils.ToBitmap(invokers), setUpAddrCache(invokers), curl, inv) assert.Equal(t, 0, len(fileredInvokers.ToArray())) } diff --git a/cluster/router/condition/listenable_router.go b/cluster/router/condition/listenable_router.go index 0b47310dbf..1e35ac8c5f 100644 --- a/cluster/router/condition/listenable_router.go +++ b/cluster/router/condition/listenable_router.go @@ -49,6 +49,7 @@ type listenableRouter struct { url *common.URL force bool priority int64 + notify chan struct{} } // RouterRule Get RouterRule instance from listenableRouter @@ -56,7 +57,7 @@ func (l *listenableRouter) RouterRule() *RouterRule { return l.routerRule } -func newListenableRouter(url *common.URL, ruleKey string) (*AppRouter, error) { +func newListenableRouter(url *common.URL, ruleKey string, notify chan struct{}) (*AppRouter, error) { if ruleKey == "" { return nil, perrors.Errorf("NewListenableRouter ruleKey is nil, can't create Listenable router") } @@ -64,6 +65,7 @@ func newListenableRouter(url *common.URL, ruleKey string) (*AppRouter, error) { l.url = url l.priority = listenableRouterDefaultPriority + l.notify = notify routerKey := ruleKey + constant.ConditionRouterRuleSuffix // add listener @@ -110,6 +112,7 @@ func (l *listenableRouter) Process(event *config_center.ConfigChangeEvent) { return } l.generateConditions(routerRule) + l.notify <- struct{}{} } func (l *listenableRouter) generateConditions(rule *RouterRule) { diff --git a/cluster/router/condition/router.go b/cluster/router/condition/router.go index 0817b32843..d543ca3f94 100644 --- a/cluster/router/condition/router.go +++ b/cluster/router/condition/router.go @@ -62,6 +62,7 @@ type ConditionRouter struct { enabled bool WhenCondition map[string]MatchPair ThenCondition map[string]MatchPair + notify chan struct{} } // NewConditionRouterWithRule Init condition router by raw rule @@ -111,7 +112,7 @@ func NewConditionRouterWithRule(rule string) (*ConditionRouter, error) { } // NewConditionRouter Init condition router by URL -func NewConditionRouter(url *common.URL) (*ConditionRouter, error) { +func NewConditionRouter(url *common.URL, notify chan struct{}) (*ConditionRouter, error) { if url == nil { return nil, perrors.Errorf("Illegal route URL!") } @@ -135,6 +136,7 @@ func NewConditionRouter(url *common.URL) (*ConditionRouter, error) { router.priority = url.GetParamInt(constant.RouterPriority, defaultPriority) router.Force = url.GetParamBool(constant.RouterForce, false) router.enabled = url.GetParamBool(constant.RouterEnabled, true) + router.notify = notify return router, nil } diff --git a/cluster/router/condition/router_test.go b/cluster/router/condition/router_test.go index a344b64efb..f3dc1fe788 100644 --- a/cluster/router/condition/router_test.go +++ b/cluster/router/condition/router_test.go @@ -58,8 +58,9 @@ func TestParseRule(t *testing.T) { } func TestNewConditionRouter(t *testing.T) { + notify := make(chan struct{}) url, _ := common.NewURL(`condition://0.0.0.0:?application=mock-app&category=routers&force=true&priority=1&router=condition&rule=YSAmIGMgPT4gYiAmIGQ%3D`) - router, err := NewConditionRouter(url) + router, err := NewConditionRouter(url, notify) assert.Nil(t, err) assert.Equal(t, true, router.Enabled()) assert.Equal(t, true, router.Force) @@ -69,22 +70,22 @@ func TestNewConditionRouter(t *testing.T) { assert.EqualValues(t, router.WhenCondition, whenRule) assert.EqualValues(t, router.ThenCondition, thenRule) - router, err = NewConditionRouter(nil) + router, err = NewConditionRouter(nil, notify) assert.Nil(t, router) assert.Error(t, err) url, _ = common.NewURL(`condition://0.0.0.0:?application=mock-app&category=routers&force=true&priority=1&router=condition&rule=YSAmT4gYiAmIGQ%3D`) - router, err = NewConditionRouter(url) + router, err = NewConditionRouter(url, notify) assert.Nil(t, router) assert.Error(t, err) url, _ = common.NewURL(`condition://0.0.0.0:?application=mock-app&category=routers&force=true&router=condition&rule=YSAmIGMgPT4gYiAmIGQ%3D`) - router, err = NewConditionRouter(url) + router, err = NewConditionRouter(url, notify) assert.Nil(t, err) assert.Equal(t, int64(150), router.Priority()) url, _ = common.NewURL(`condition://0.0.0.0:?category=routers&force=true&interface=mock-service&router=condition&rule=YSAmIGMgPT4gYiAmIGQ%3D`) - router, err = NewConditionRouter(url) + router, err = NewConditionRouter(url, notify) assert.Nil(t, err) assert.Equal(t, int64(140), router.Priority()) } diff --git a/cluster/router/conncheck/conn_check_route.go b/cluster/router/conncheck/conn_check_route.go index 8d94db409b..97f049d85b 100644 --- a/cluster/router/conncheck/conn_check_route.go +++ b/cluster/router/conncheck/conn_check_route.go @@ -40,12 +40,14 @@ const ( type ConnCheckRouter struct { url *common.URL checker router.ConnChecker + notify chan struct{} } // NewConnCheckRouter construct an NewConnCheckRouter via url -func NewConnCheckRouter(url *common.URL) (router.PriorityRouter, error) { +func NewConnCheckRouter(url *common.URL, notify chan struct{}) (router.PriorityRouter, error) { r := &ConnCheckRouter{ - url: url, + url: url, + notify: notify, } checkerName := url.GetParam(constant.HEALTH_CHECKER, constant.DEFAULT_HEALTH_CHECKER) r.checker = extension.GetConnChecker(checkerName, url) diff --git a/cluster/router/conncheck/conn_check_route_test.go b/cluster/router/conncheck/conn_check_route_test.go index 95b8d4a928..c9aff023fb 100644 --- a/cluster/router/conncheck/conn_check_route_test.go +++ b/cluster/router/conncheck/conn_check_route_test.go @@ -48,11 +48,12 @@ const ( func TestConnCheckRouterRoute(t *testing.T) { defer protocol.CleanAllStatus() + notify := make(chan struct{}) consumerURL, _ := common.NewURL(connCheck1001URL) url1, _ := common.NewURL(fmt.Sprintf(connCheckRouteUrlFormat, connCheckRoute1010IP)) url2, _ := common.NewURL(fmt.Sprintf(connCheckRouteUrlFormat, connCheckRoute1011IP)) url3, _ := common.NewURL(fmt.Sprintf(connCheckRouteUrlFormat, connCheckRoute1012IP)) - hcr, _ := NewConnCheckRouter(consumerURL) + hcr, _ := NewConnCheckRouter(consumerURL, notify) var invokers []protocol.Invoker invoker1 := NewMockInvoker(url1) diff --git a/cluster/router/conncheck/factory.go b/cluster/router/conncheck/factory.go index 12498d18d8..a7b19aaea6 100644 --- a/cluster/router/conncheck/factory.go +++ b/cluster/router/conncheck/factory.go @@ -39,6 +39,6 @@ func newConnCheckRouteFactory() router.PriorityRouterFactory { } // NewPriorityRouter construct a new NewConnCheckRouter via url -func (f *ConnCheckRouteFactory) NewPriorityRouter(url *common.URL) (router.PriorityRouter, error) { - return NewConnCheckRouter(url) +func (f *ConnCheckRouteFactory) NewPriorityRouter(url *common.URL, notify chan struct{}) (router.PriorityRouter, error) { + return NewConnCheckRouter(url, notify) } diff --git a/cluster/router/healthcheck/factory.go b/cluster/router/healthcheck/factory.go index 40c9dd7ab9..a9054c7714 100644 --- a/cluster/router/healthcheck/factory.go +++ b/cluster/router/healthcheck/factory.go @@ -38,6 +38,6 @@ func newHealthCheckRouteFactory() router.PriorityRouterFactory { } // NewPriorityRouter construct a new NewHealthCheckRouter via url -func (f *HealthCheckRouteFactory) NewPriorityRouter(url *common.URL) (router.PriorityRouter, error) { - return NewHealthCheckRouter(url) +func (f *HealthCheckRouteFactory) NewPriorityRouter(url *common.URL, notify chan struct{}) (router.PriorityRouter, error) { + return NewHealthCheckRouter(url, notify) } diff --git a/cluster/router/healthcheck/health_check_route.go b/cluster/router/healthcheck/health_check_route.go index 42a802f947..bd9543e1b2 100644 --- a/cluster/router/healthcheck/health_check_route.go +++ b/cluster/router/healthcheck/health_check_route.go @@ -41,13 +41,15 @@ type HealthCheckRouter struct { url *common.URL enabled bool checker router.HealthChecker + notify chan struct{} } // NewHealthCheckRouter construct an HealthCheckRouter via url -func NewHealthCheckRouter(url *common.URL) (router.PriorityRouter, error) { +func NewHealthCheckRouter(url *common.URL, notify chan struct{}) (router.PriorityRouter, error) { r := &HealthCheckRouter{ url: url, enabled: url.GetParamBool(constant.HEALTH_ROUTE_ENABLED_KEY, false), + notify: notify, } if r.enabled { checkerName := url.GetParam(constant.HEALTH_CHECKER, constant.DEFAULT_HEALTH_CHECKER) diff --git a/cluster/router/healthcheck/health_check_route_test.go b/cluster/router/healthcheck/health_check_route_test.go index f088be531a..62b690dcd6 100644 --- a/cluster/router/healthcheck/health_check_route_test.go +++ b/cluster/router/healthcheck/health_check_route_test.go @@ -49,12 +49,13 @@ const ( func TestHealthCheckRouterRoute(t *testing.T) { defer protocol.CleanAllStatus() + notify := make(chan struct{}) consumerURL, _ := common.NewURL(healthCheck1001URL) consumerURL.SetParam(constant.HEALTH_ROUTE_ENABLED_KEY, "true") url1, _ := common.NewURL(fmt.Sprintf(healthCheckRouteUrlFormat, healthCheckRoute1010IP)) url2, _ := common.NewURL(fmt.Sprintf(healthCheckRouteUrlFormat, healthCheckRoute1011IP)) url3, _ := common.NewURL(fmt.Sprintf(healthCheckRouteUrlFormat, healthCheckRoute1012IP)) - hcr, _ := NewHealthCheckRouter(consumerURL) + hcr, _ := NewHealthCheckRouter(consumerURL, notify) var invokers []protocol.Invoker invoker1 := NewMockInvoker(url1) @@ -112,13 +113,14 @@ func TestHealthCheckRouterRoute(t *testing.T) { func TestNewHealthCheckRouter(t *testing.T) { defer protocol.CleanAllStatus() + notify := make(chan struct{}) url, _ := common.NewURL(fmt.Sprintf(healthCheckDubboUrlFormat, healthCheckDubbo1010IP)) - hcr, _ := NewHealthCheckRouter(url) + hcr, _ := NewHealthCheckRouter(url, notify) h := hcr.(*HealthCheckRouter) assert.Nil(t, h.checker) url.SetParam(constant.HEALTH_ROUTE_ENABLED_KEY, "true") - hcr, _ = NewHealthCheckRouter(url) + hcr, _ = NewHealthCheckRouter(url, notify) h = hcr.(*HealthCheckRouter) assert.NotNil(t, h.checker) @@ -130,7 +132,7 @@ func TestNewHealthCheckRouter(t *testing.T) { url.SetParam(constant.CIRCUIT_TRIPPED_TIMEOUT_FACTOR_KEY, "500") url.SetParam(constant.SUCCESSIVE_FAILED_REQUEST_THRESHOLD_KEY, "10") url.SetParam(constant.OUTSTANDING_REQUEST_COUNT_LIMIT_KEY, "1000") - hcr, _ = NewHealthCheckRouter(url) + hcr, _ = NewHealthCheckRouter(url, notify) h = hcr.(*HealthCheckRouter) dhc = h.checker.(*DefaultHealthChecker) assert.Equal(t, dhc.outStandingRequestConutLimit, int32(1000)) diff --git a/cluster/router/router.go b/cluster/router/router.go index 8a19dcf8cc..1d71554f6b 100644 --- a/cluster/router/router.go +++ b/cluster/router/router.go @@ -30,7 +30,7 @@ import ( // PriorityRouterFactory creates creates priority router with url type PriorityRouterFactory interface { // NewPriorityRouter creates router instance with URL - NewPriorityRouter(*common.URL) (PriorityRouter, error) + NewPriorityRouter(*common.URL, chan struct{}) (PriorityRouter, error) } // FilePriorityRouterFactory creates priority router with parse config file diff --git a/cluster/router/tag/factory.go b/cluster/router/tag/factory.go index a5d989cd31..fd2c15cddf 100644 --- a/cluster/router/tag/factory.go +++ b/cluster/router/tag/factory.go @@ -37,8 +37,8 @@ func NewTagRouterFactory() router.PriorityRouterFactory { // NewPriorityRouter create a tagRouter by tagRouterFactory with a url // The url contains router configuration information -func (c *tagRouterFactory) NewPriorityRouter(url *common.URL) (router.PriorityRouter, error) { - return NewTagRouter(url) +func (c *tagRouterFactory) NewPriorityRouter(url *common.URL, notify chan struct{}) (router.PriorityRouter, error) { + return NewTagRouter(url, notify) } // NewFileRouter create a tagRouter by profile content diff --git a/cluster/router/tag/factory_test.go b/cluster/router/tag/factory_test.go index b350bb2a91..85a0ff010a 100644 --- a/cluster/router/tag/factory_test.go +++ b/cluster/router/tag/factory_test.go @@ -39,7 +39,8 @@ func TestTagRouterFactoryNewRouter(t *testing.T) { u1, err := common.NewURL(fmt.Sprintf(factoryFormat, factoryLocalIP)) assert.Nil(t, err) factory := NewTagRouterFactory() - tagRouter, e := factory.NewPriorityRouter(u1) + notify := make(chan struct{}) + tagRouter, e := factory.NewPriorityRouter(u1, notify) assert.Nil(t, e) assert.NotNil(t, tagRouter) } diff --git a/cluster/router/tag/file.go b/cluster/router/tag/file.go index 94daf1508e..85507f7eb1 100644 --- a/cluster/router/tag/file.go +++ b/cluster/router/tag/file.go @@ -45,6 +45,7 @@ type FileTagRouter struct { } // NewFileTagRouter Create file tag router instance with content (from config file) +// todo fix this router, now it is useless, tag router is nil func NewFileTagRouter(content []byte) (*FileTagRouter, error) { fileRouter := &FileTagRouter{} rule, err := getRule(string(content)) @@ -52,7 +53,8 @@ func NewFileTagRouter(content []byte) (*FileTagRouter, error) { return nil, perrors.Errorf("yaml.Unmarshal() failed , error:%v", perrors.WithStack(err)) } fileRouter.routerRule = rule - fileRouter.router, err = NewTagRouter(fileRouter.URL()) + notify := make(chan struct{}) + fileRouter.router, err = NewTagRouter(fileRouter.URL(), notify) return fileRouter, err } diff --git a/cluster/router/tag/tag_router.go b/cluster/router/tag/tag_router.go index c7f53047c1..87f944a25a 100644 --- a/cluster/router/tag/tag_router.go +++ b/cluster/router/tag/tag_router.go @@ -76,10 +76,11 @@ type tagRouter struct { application string ruleChanged bool mutex sync.RWMutex + notify chan struct{} } // NewTagRouter returns a tagRouter instance if url is not nil -func NewTagRouter(url *common.URL) (*tagRouter, error) { +func NewTagRouter(url *common.URL, notify chan struct{}) (*tagRouter, error) { if url == nil { return nil, perrors.Errorf("Illegal route URL!") } @@ -87,6 +88,7 @@ func NewTagRouter(url *common.URL) (*tagRouter, error) { url: url, enabled: url.GetParamBool(constant.RouterEnabled, true), priority: url.GetParamInt(constant.RouterPriority, 0), + notify: notify, }, nil } @@ -191,6 +193,7 @@ func (c *tagRouter) Process(event *config_center.ConfigChangeEvent) { defer c.mutex.Unlock() c.tagRouterRule = routerRule c.ruleChanged = true + c.notify <- struct{}{} } // URL gets the url of tagRouter diff --git a/cluster/router/tag/tag_router_test.go b/cluster/router/tag/tag_router_test.go index 3f7b979f3d..68fd062371 100644 --- a/cluster/router/tag/tag_router_test.go +++ b/cluster/router/tag/tag_router_test.go @@ -120,17 +120,19 @@ func (bi *MockInvoker) Destroy() { func TestTagRouterPriority(t *testing.T) { u1, err := common.NewURL(tagRouterTestUserConsumerTag) + notify := make(chan struct{}) assert.Nil(t, err) - tagRouter, e := NewTagRouter(u1) + tagRouter, e := NewTagRouter(u1, notify) assert.Nil(t, e) p := tagRouter.Priority() assert.Equal(t, int64(0), p) } func TestTagRouterRouteForce(t *testing.T) { + notify := make(chan struct{}) u1, e1 := common.NewURL(tagRouterTestUserConsumerTag) assert.Nil(t, e1) - tagRouter, e := NewTagRouter(u1) + tagRouter, e := NewTagRouter(u1, notify) assert.Nil(t, e) u2, e2 := common.NewURL(tagRouterTestHangZhouUrl) @@ -162,7 +164,8 @@ func TestTagRouterRouteForce(t *testing.T) { func TestTagRouterRouteNoForce(t *testing.T) { u1, e1 := common.NewURL(tagRouterTestUserConsumer) assert.Nil(t, e1) - tagRouter, e := NewTagRouter(u1) + notify := make(chan struct{}) + tagRouter, e := NewTagRouter(u1, notify) assert.Nil(t, e) u2, e2 := common.NewURL(tagRouterTestHangZhouUrl) @@ -225,7 +228,8 @@ func TestRouteBeijingInvoker(t *testing.T) { invokers = append(invokers, inv2, inv3, inv4, inv5) url, _ := common.NewURL(tagRouterTestBeijingUrl) - tagRouter, _ := NewTagRouter(url) + notify := make(chan struct{}) + tagRouter, _ := NewTagRouter(url, notify) rb := roaring.NewBitmap() rb.AddRange(0, uint64(len(invokers))) @@ -301,7 +305,8 @@ tags: url, e1 := common.NewURL(tagRouterTestUserConsumerTag) suite.Nil(e1) - tagRouter, err := NewTagRouter(url) + notify := make(chan struct{}) + tagRouter, err := NewTagRouter(url, notify) suite.Nil(err) suite.NotNil(tagRouter) suite.route = tagRouter @@ -365,7 +370,8 @@ func (suite *DynamicTagRouter) TestDynamicTagRouterByNoTagAndAddressMatch() { func TestProcess(t *testing.T) { u1, err := common.NewURL(tagRouterTestUserConsumerTag) assert.Nil(t, err) - tagRouter, e := NewTagRouter(u1) + notify := make(chan struct{}) + tagRouter, e := NewTagRouter(u1, notify) assert.Nil(t, e) assert.NotNil(t, tagRouter) @@ -383,12 +389,18 @@ tags: - name: hangzhou addresses: [192.168.1.3, 192.168.1.4] ` + go func() { + for { + <-notify + } + }() tagRouter.Process(&config_center.ConfigChangeEvent{Value: testYML, ConfigType: remoting.EventTypeAdd}) assert.NotNil(t, tagRouter.tagRouterRule) assert.Equal(t, []string{"beijing", "hangzhou"}, tagRouter.tagRouterRule.getTagNames()) assert.Equal(t, []string{"192.168.1.1", "192.168.1.2", "192.168.1.3", "192.168.1.4"}, tagRouter.tagRouterRule.getAddresses()) assert.Equal(t, []string{"192.168.1.3", "192.168.1.4"}, tagRouter.tagRouterRule.getTagNameToAddresses()["hangzhou"]) assert.Equal(t, []string{"beijing"}, tagRouter.tagRouterRule.getAddressToTagNames()["192.168.1.1"]) + tagRouter.Process(&config_center.ConfigChangeEvent{ConfigType: remoting.EventTypeDel}) assert.Nil(t, tagRouter.tagRouterRule) } From c634ab2724ec21fcdb1e1620c226f1066da29b62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=BF=97=E4=BF=A1?= Date: Thu, 31 Dec 2020 11:50:29 +0800 Subject: [PATCH 20/39] fix: new base directory func add default chain --- cluster/directory/base_directory.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cluster/directory/base_directory.go b/cluster/directory/base_directory.go index 309cd4429c..caba0f3ba0 100644 --- a/cluster/directory/base_directory.go +++ b/cluster/directory/base_directory.go @@ -45,10 +45,11 @@ type BaseDirectory struct { // NewBaseDirectory Create BaseDirectory with URL func NewBaseDirectory(url *common.URL) BaseDirectory { + rc, _ := chain.NewRouterChain(url) return BaseDirectory{ url: url, destroyed: atomic.NewBool(false), - routerChain: &chain.RouterChain{}, + routerChain: rc, } } From 4bce4312cfdd3a95db5ca5d02d6327890da5f9d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=BF=97=E4=BF=A1?= Date: Thu, 31 Dec 2020 13:51:59 +0800 Subject: [PATCH 21/39] fix: base directory_test good --- cluster/directory/base_directory.go | 3 +-- cluster/directory/base_directory_test.go | 5 ++++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/cluster/directory/base_directory.go b/cluster/directory/base_directory.go index caba0f3ba0..309cd4429c 100644 --- a/cluster/directory/base_directory.go +++ b/cluster/directory/base_directory.go @@ -45,11 +45,10 @@ type BaseDirectory struct { // NewBaseDirectory Create BaseDirectory with URL func NewBaseDirectory(url *common.URL) BaseDirectory { - rc, _ := chain.NewRouterChain(url) return BaseDirectory{ url: url, destroyed: atomic.NewBool(false), - routerChain: rc, + routerChain: &chain.RouterChain{}, } } diff --git a/cluster/directory/base_directory_test.go b/cluster/directory/base_directory_test.go index 16e3c5a960..9208c62364 100644 --- a/cluster/directory/base_directory_test.go +++ b/cluster/directory/base_directory_test.go @@ -20,6 +20,7 @@ package directory import ( "encoding/base64" "fmt" + chain2 "github.com/apache/dubbo-go/cluster/router/chain" "testing" ) @@ -50,7 +51,9 @@ func TestBuildRouterChain(t *testing.T) { regURL := url regURL.AddParam(constant.INTERFACE_KEY, "mock-app") directory := NewBaseDirectory(regURL) - + var err error + directory.routerChain, err = chain2.NewRouterChain(regURL) + assert.Nil(t, err) localIP := common.GetLocalIp() rule := base64.URLEncoding.EncodeToString([]byte("true => " + " host = " + localIP)) routeURL := getRouteURL(rule, anyURL) From f5030fe5d8e56efb5d69ec82349e34e1c5d37bc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=BF=97=E4=BF=A1?= Date: Thu, 31 Dec 2020 14:24:48 +0800 Subject: [PATCH 22/39] fix: fix test and add another gr to push notify --- cluster/router/chain/chain.go | 4 +++- cluster/router/chain/chain_test.go | 5 +++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/cluster/router/chain/chain.go b/cluster/router/chain/chain.go index 57788975e7..0e175ddf23 100644 --- a/cluster/router/chain/chain.go +++ b/cluster/router/chain/chain.go @@ -104,7 +104,9 @@ func (c *RouterChain) AddRouters(routers []router.PriorityRouter) { c.mutex.Lock() defer c.mutex.Unlock() c.routers = newRouters - c.notify <- struct{}{} + go func() { + c.notify <- struct{}{} + }() } // SetInvokers receives updated invokers from registry center. If the times of notification exceeds countThreshold and diff --git a/cluster/router/chain/chain_test.go b/cluster/router/chain/chain_test.go index f274d1b318..b4b3d72700 100644 --- a/cluster/router/chain/chain_test.go +++ b/cluster/router/chain/chain_test.go @@ -143,6 +143,11 @@ conditions: assert.NotNil(t, url) factory := extension.GetRouterFactory(url.Protocol) notify := make(chan struct{}) + go func() { + for { + <-notify + } + }() r, err := factory.NewPriorityRouter(url, notify) assert.Nil(t, err) assert.NotNil(t, r) From c5532cb171a2738aa8d69d406189f01ce48d8a76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=BF=97=E4=BF=A1?= Date: Thu, 31 Dec 2020 14:47:26 +0800 Subject: [PATCH 23/39] fix test notify bug --- cluster/directory/base_directory_test.go | 4 +- cluster/router/condition/app_router_test.go | 15 ++++++ cluster/router/condition/factory_test.go | 60 +++++++++++++++++++++ cluster/router/condition/router_test.go | 5 ++ 4 files changed, 82 insertions(+), 2 deletions(-) diff --git a/cluster/directory/base_directory_test.go b/cluster/directory/base_directory_test.go index 9208c62364..443f07de2c 100644 --- a/cluster/directory/base_directory_test.go +++ b/cluster/directory/base_directory_test.go @@ -20,7 +20,6 @@ package directory import ( "encoding/base64" "fmt" - chain2 "github.com/apache/dubbo-go/cluster/router/chain" "testing" ) @@ -29,6 +28,7 @@ import ( ) import ( + "github.com/apache/dubbo-go/cluster/router/chain" _ "github.com/apache/dubbo-go/cluster/router/condition" "github.com/apache/dubbo-go/common" "github.com/apache/dubbo-go/common/constant" @@ -52,7 +52,7 @@ func TestBuildRouterChain(t *testing.T) { regURL.AddParam(constant.INTERFACE_KEY, "mock-app") directory := NewBaseDirectory(regURL) var err error - directory.routerChain, err = chain2.NewRouterChain(regURL) + directory.routerChain, err = chain.NewRouterChain(regURL) assert.Nil(t, err) localIP := common.GetLocalIp() rule := base64.URLEncoding.EncodeToString([]byte("true => " + " host = " + localIP)) diff --git a/cluster/router/condition/app_router_test.go b/cluster/router/condition/app_router_test.go index c47aaaf80b..29fddfb895 100644 --- a/cluster/router/condition/app_router_test.go +++ b/cluster/router/condition/app_router_test.go @@ -79,6 +79,11 @@ conditions: appRouteURL := getAppRouteURL(routerKey) notify := make(chan struct{}) + go func() { + for { + <-notify + } + }() appRouter, err := NewAppRouter(appRouteURL, notify) assert.Nil(t, err) assert.NotNil(t, appRouter) @@ -128,6 +133,11 @@ conditions: appRouteURL := getAppRouteURL(routerKey) notify := make(chan struct{}) + go func() { + for { + <-notify + } + }() appRouter, err := NewAppRouter(appRouteURL, notify) assert.Nil(t, err) assert.NotNil(t, appRouter) @@ -168,6 +178,11 @@ conditions: appRouteURL := getAppRouteURL(routerKey) notify := make(chan struct{}) + go func() { + for { + <-notify + } + }() appRouter, err := NewAppRouter(appRouteURL, notify) assert.Nil(t, err) assert.NotNil(t, appRouter) diff --git a/cluster/router/condition/factory_test.go b/cluster/router/condition/factory_test.go index c8cc9c9761..efbc4057bf 100644 --- a/cluster/router/condition/factory_test.go +++ b/cluster/router/condition/factory_test.go @@ -133,6 +133,11 @@ func TestRoute_matchWhen(t *testing.T) { inv := &invocation.RPCInvocation{} rule := base64.URLEncoding.EncodeToString([]byte("=> host = 1.2.3.4")) notify := make(chan struct{}) + go func() { + for { + <-notify + } + }() router, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule), notify) cUrl, _ := common.NewURL(fmt.Sprintf(factoryDubboFormat, factory1111Ip)) matchWhen := router.(*ConditionRouter).MatchWhen(cUrl, inv) @@ -165,6 +170,11 @@ func TestRoute_matchWhen(t *testing.T) { func TestRoute_matchFilter(t *testing.T) { notify := make(chan struct{}) + go func() { + for { + <-notify + } + }() localIP := common.GetLocalIp() t.Logf("The local ip is %s", localIP) url1, _ := common.NewURL("dubbo://10.20.3.3:20880/com.foo.BarService?default.serialization=fastjson") @@ -201,6 +211,11 @@ func TestRoute_matchFilter(t *testing.T) { func TestRoute_methodRoute(t *testing.T) { notify := make(chan struct{}) + go func() { + for { + <-notify + } + }() inv := invocation.NewRPCInvocationWithOptions(invocation.WithMethodName("getFoo"), invocation.WithParameterTypes([]reflect.Type{}), invocation.WithArguments([]interface{}{})) rule := base64.URLEncoding.EncodeToString([]byte("host !=4.4.4.* & host = 2.2.2.2,1.1.1.1,3.3.3.3 => host = 1.2.3.4")) r, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule), notify) @@ -225,6 +240,11 @@ func TestRoute_methodRoute(t *testing.T) { func TestRoute_ReturnFalse(t *testing.T) { notify := make(chan struct{}) + go func() { + for { + <-notify + } + }() url, _ := common.NewURL("") localIP := common.GetLocalIp() invokers := []protocol.Invoker{NewMockInvoker(url, 1), NewMockInvoker(url, 2), NewMockInvoker(url, 3)} @@ -238,6 +258,11 @@ func TestRoute_ReturnFalse(t *testing.T) { func TestRoute_ReturnEmpty(t *testing.T) { notify := make(chan struct{}) + go func() { + for { + <-notify + } + }() localIP := common.GetLocalIp() url, _ := common.NewURL("") invokers := []protocol.Invoker{NewMockInvoker(url, 1), NewMockInvoker(url, 2), NewMockInvoker(url, 3)} @@ -251,6 +276,11 @@ func TestRoute_ReturnEmpty(t *testing.T) { func TestRoute_ReturnAll(t *testing.T) { notify := make(chan struct{}) + go func() { + for { + <-notify + } + }() localIP := common.GetLocalIp() urlString := "dubbo://" + localIP + "/com.foo.BarService" dubboURL, _ := common.NewURL(urlString) @@ -272,6 +302,11 @@ func TestRoute_HostFilter(t *testing.T) { url2, _ := common.NewURL(fmt.Sprintf(factoryDubboFormat, localIP)) url3, _ := common.NewURL(fmt.Sprintf(factoryDubboFormat, localIP)) notify := make(chan struct{}) + go func() { + for { + <-notify + } + }() invoker1 := NewMockInvoker(url1, 1) invoker2 := NewMockInvoker(url2, 2) invoker3 := NewMockInvoker(url3, 3) @@ -288,6 +323,11 @@ func TestRoute_HostFilter(t *testing.T) { func TestRoute_Empty_HostFilter(t *testing.T) { notify := make(chan struct{}) + go func() { + for { + <-notify + } + }() localIP := common.GetLocalIp() url1, _ := common.NewURL(factory333URL) url2, _ := common.NewURL(fmt.Sprintf(factoryDubboFormat, localIP)) @@ -308,6 +348,11 @@ func TestRoute_Empty_HostFilter(t *testing.T) { func TestRoute_False_HostFilter(t *testing.T) { notify := make(chan struct{}) + go func() { + for { + <-notify + } + }() localIP := common.GetLocalIp() url1, _ := common.NewURL(factory333URL) url2, _ := common.NewURL(fmt.Sprintf(factoryDubboFormat, localIP)) @@ -328,6 +373,11 @@ func TestRoute_False_HostFilter(t *testing.T) { func TestRoute_Placeholder(t *testing.T) { notify := make(chan struct{}) + go func() { + for { + <-notify + } + }() localIP := common.GetLocalIp() url1, _ := common.NewURL(factory333URL) url2, _ := common.NewURL(fmt.Sprintf(factoryDubboFormat, localIP)) @@ -348,6 +398,11 @@ func TestRoute_Placeholder(t *testing.T) { func TestRoute_NoForce(t *testing.T) { notify := make(chan struct{}) + go func() { + for { + <-notify + } + }() localIP := common.GetLocalIp() url1, _ := common.NewURL(factory333URL) url2, _ := common.NewURL(fmt.Sprintf(factoryDubboFormat, localIP)) @@ -366,6 +421,11 @@ func TestRoute_NoForce(t *testing.T) { func TestRoute_Force(t *testing.T) { notify := make(chan struct{}) + go func() { + for { + <-notify + } + }() localIP := common.GetLocalIp() url1, _ := common.NewURL(factory333URL) url2, _ := common.NewURL(fmt.Sprintf(factoryDubboFormat, localIP)) diff --git a/cluster/router/condition/router_test.go b/cluster/router/condition/router_test.go index f3dc1fe788..15bf76f085 100644 --- a/cluster/router/condition/router_test.go +++ b/cluster/router/condition/router_test.go @@ -59,6 +59,11 @@ func TestParseRule(t *testing.T) { func TestNewConditionRouter(t *testing.T) { notify := make(chan struct{}) + go func() { + for { + <-notify + } + }() url, _ := common.NewURL(`condition://0.0.0.0:?application=mock-app&category=routers&force=true&priority=1&router=condition&rule=YSAmIGMgPT4gYiAmIGQ%3D`) router, err := NewConditionRouter(url, notify) assert.Nil(t, err) From b8127947cde55da68f118ee6ad9bc9bf4d91f45e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=BF=97=E4=BF=A1?= Date: Thu, 31 Dec 2020 14:47:51 +0800 Subject: [PATCH 24/39] fix test notify bug --- .../router/conncheck/conn_check_route_test.go | 5 ++++ .../healthcheck/health_check_route_test.go | 10 +++++++ cluster/router/tag/factory_test.go | 5 ++++ cluster/router/tag/tag_router_test.go | 30 +++++++++++++++++++ 4 files changed, 50 insertions(+) diff --git a/cluster/router/conncheck/conn_check_route_test.go b/cluster/router/conncheck/conn_check_route_test.go index c9aff023fb..5277b0870b 100644 --- a/cluster/router/conncheck/conn_check_route_test.go +++ b/cluster/router/conncheck/conn_check_route_test.go @@ -49,6 +49,11 @@ const ( func TestConnCheckRouterRoute(t *testing.T) { defer protocol.CleanAllStatus() notify := make(chan struct{}) + go func() { + for { + <-notify + } + }() consumerURL, _ := common.NewURL(connCheck1001URL) url1, _ := common.NewURL(fmt.Sprintf(connCheckRouteUrlFormat, connCheckRoute1010IP)) url2, _ := common.NewURL(fmt.Sprintf(connCheckRouteUrlFormat, connCheckRoute1011IP)) diff --git a/cluster/router/healthcheck/health_check_route_test.go b/cluster/router/healthcheck/health_check_route_test.go index 62b690dcd6..1d44eb1a35 100644 --- a/cluster/router/healthcheck/health_check_route_test.go +++ b/cluster/router/healthcheck/health_check_route_test.go @@ -50,6 +50,11 @@ const ( func TestHealthCheckRouterRoute(t *testing.T) { defer protocol.CleanAllStatus() notify := make(chan struct{}) + go func() { + for { + <-notify + } + }() consumerURL, _ := common.NewURL(healthCheck1001URL) consumerURL.SetParam(constant.HEALTH_ROUTE_ENABLED_KEY, "true") url1, _ := common.NewURL(fmt.Sprintf(healthCheckRouteUrlFormat, healthCheckRoute1010IP)) @@ -114,6 +119,11 @@ func TestHealthCheckRouterRoute(t *testing.T) { func TestNewHealthCheckRouter(t *testing.T) { defer protocol.CleanAllStatus() notify := make(chan struct{}) + go func() { + for { + <-notify + } + }() url, _ := common.NewURL(fmt.Sprintf(healthCheckDubboUrlFormat, healthCheckDubbo1010IP)) hcr, _ := NewHealthCheckRouter(url, notify) h := hcr.(*HealthCheckRouter) diff --git a/cluster/router/tag/factory_test.go b/cluster/router/tag/factory_test.go index 85a0ff010a..ea5ff63fa0 100644 --- a/cluster/router/tag/factory_test.go +++ b/cluster/router/tag/factory_test.go @@ -40,6 +40,11 @@ func TestTagRouterFactoryNewRouter(t *testing.T) { assert.Nil(t, err) factory := NewTagRouterFactory() notify := make(chan struct{}) + go func() { + for { + <-notify + } + }() tagRouter, e := factory.NewPriorityRouter(u1, notify) assert.Nil(t, e) assert.NotNil(t, tagRouter) diff --git a/cluster/router/tag/tag_router_test.go b/cluster/router/tag/tag_router_test.go index 68fd062371..d7234a3392 100644 --- a/cluster/router/tag/tag_router_test.go +++ b/cluster/router/tag/tag_router_test.go @@ -121,6 +121,11 @@ func (bi *MockInvoker) Destroy() { func TestTagRouterPriority(t *testing.T) { u1, err := common.NewURL(tagRouterTestUserConsumerTag) notify := make(chan struct{}) + go func() { + for { + <-notify + } + }() assert.Nil(t, err) tagRouter, e := NewTagRouter(u1, notify) assert.Nil(t, e) @@ -130,6 +135,11 @@ func TestTagRouterPriority(t *testing.T) { func TestTagRouterRouteForce(t *testing.T) { notify := make(chan struct{}) + go func() { + for { + <-notify + } + }() u1, e1 := common.NewURL(tagRouterTestUserConsumerTag) assert.Nil(t, e1) tagRouter, e := NewTagRouter(u1, notify) @@ -165,6 +175,11 @@ func TestTagRouterRouteNoForce(t *testing.T) { u1, e1 := common.NewURL(tagRouterTestUserConsumer) assert.Nil(t, e1) notify := make(chan struct{}) + go func() { + for { + <-notify + } + }() tagRouter, e := NewTagRouter(u1, notify) assert.Nil(t, e) @@ -229,6 +244,11 @@ func TestRouteBeijingInvoker(t *testing.T) { url, _ := common.NewURL(tagRouterTestBeijingUrl) notify := make(chan struct{}) + go func() { + for { + <-notify + } + }() tagRouter, _ := NewTagRouter(url, notify) rb := roaring.NewBitmap() @@ -306,6 +326,11 @@ tags: suite.Nil(e1) notify := make(chan struct{}) + go func() { + for { + <-notify + } + }() tagRouter, err := NewTagRouter(url, notify) suite.Nil(err) suite.NotNil(tagRouter) @@ -371,6 +396,11 @@ func TestProcess(t *testing.T) { u1, err := common.NewURL(tagRouterTestUserConsumerTag) assert.Nil(t, err) notify := make(chan struct{}) + go func() { + for { + <-notify + } + }() tagRouter, e := NewTagRouter(u1, notify) assert.Nil(t, e) assert.NotNil(t, tagRouter) From 5fe602954da196f2c08b2c50942d5d72106b57b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=BF=97=E4=BF=A1?= Date: Thu, 31 Dec 2020 16:39:22 +0800 Subject: [PATCH 25/39] fix: add notify test --- cluster/router/condition/listenable_router.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cluster/router/condition/listenable_router.go b/cluster/router/condition/listenable_router.go index 1e35ac8c5f..2e55b2075d 100644 --- a/cluster/router/condition/listenable_router.go +++ b/cluster/router/condition/listenable_router.go @@ -112,7 +112,9 @@ func (l *listenableRouter) Process(event *config_center.ConfigChangeEvent) { return } l.generateConditions(routerRule) - l.notify <- struct{}{} + go func() { + l.notify <- struct{}{} + }() } func (l *listenableRouter) generateConditions(rule *RouterRule) { From b6022bbd868305854f51e07312d8d5c3eacdea03 Mon Sep 17 00:00:00 2001 From: AlexStocks Date: Mon, 4 Jan 2021 15:06:32 +0800 Subject: [PATCH 26/39] fix ctx linter error --- common/constant/key.go | 2 +- common/url.go | 8 ++-- common/url_test.go | 42 +++++++++++++++---- config_center/apollo/listener.go | 2 +- .../tps/tps_limiter_method_service_test.go | 2 +- remoting/getty/listener_test.go | 6 +-- 6 files changed, 44 insertions(+), 18 deletions(-) diff --git a/common/constant/key.go b/common/constant/key.go index 12e3096e5a..50aea81371 100644 --- a/common/constant/key.go +++ b/common/constant/key.go @@ -200,7 +200,7 @@ const ( ) const ( - TRACING_REMOTE_SPAN_CTX = "tracing.remote.span.ctx" + TRACING_REMOTE_SPAN_CTX = DubboCtxKey("tracing.remote.span.ctx") ) // Use for router module diff --git a/common/url.go b/common/url.go index 87cacfd7fb..ac49465346 100644 --- a/common/url.go +++ b/common/url.go @@ -90,9 +90,7 @@ type baseUrl struct { Location string // ip+port Ip string Port string - //url.Values is not safe map, add to avoid concurrent map read and map write error - paramsLock sync.RWMutex - params url.Values + PrimitiveURL string } @@ -116,6 +114,10 @@ type URL struct { noCopy noCopy baseUrl + //url.Values is not safe map, add to avoid concurrent map read and map write error + paramsLock sync.RWMutex + params url.Values + Path string // like /com.ikurento.dubbo.UserProvider Username string Password string diff --git a/common/url_test.go b/common/url_test.go index 4008f6a3d3..c645f1a046 100644 --- a/common/url_test.go +++ b/common/url_test.go @@ -161,7 +161,10 @@ func TestURLEqual(t *testing.T) { func TestURLGetParam(t *testing.T) { params := url.Values{} params.Set("key", "value") - u := URL{baseUrl: baseUrl{params: params}} + + u := URL{} + u.SetParams(params) + v := u.GetParam("key", "default") assert.Equal(t, "value", v) @@ -172,8 +175,11 @@ func TestURLGetParam(t *testing.T) { func TestURLGetParamInt(t *testing.T) { params := url.Values{} - params.Set("key", "") - u := URL{baseUrl: baseUrl{params: params}} + params.Set("key", "value") + + u := URL{} + u.SetParams(params) + v := u.GetParamInt("key", 1) assert.Equal(t, int64(1), v) @@ -185,7 +191,10 @@ func TestURLGetParamInt(t *testing.T) { func TestURLGetParamIntValue(t *testing.T) { params := url.Values{} params.Set("key", "0") - u := URL{baseUrl: baseUrl{params: params}} + + u := URL{} + u.SetParams(params) + v := u.GetParamInt("key", 1) assert.Equal(t, int64(0), v) @@ -197,7 +206,10 @@ func TestURLGetParamIntValue(t *testing.T) { func TestURLGetParamBool(t *testing.T) { params := url.Values{} params.Set("force", "true") - u := URL{baseUrl: baseUrl{params: params}} + + u := URL{} + u.SetParams(params) + v := u.GetParamBool("force", false) assert.Equal(t, true, v) @@ -210,7 +222,10 @@ func TestURLGetParamAndDecoded(t *testing.T) { rule := "host = 2.2.2.2,1.1.1.1,3.3.3.3 & host !=1.1.1.1 => host = 1.2.3.4" params := url.Values{} params.Set("rule", base64.URLEncoding.EncodeToString([]byte(rule))) - u := URL{baseUrl: baseUrl{params: params}} + + u := URL{} + u.SetParams(params) + v, _ := u.GetParamAndDecoded("rule") assert.Equal(t, rule, v) } @@ -247,7 +262,10 @@ func TestURLToMap(t *testing.T) { func TestURLGetMethodParamInt(t *testing.T) { params := url.Values{} params.Set("methods.GetValue.timeout", "3") - u := URL{baseUrl: baseUrl{params: params}} + + u := URL{} + u.SetParams(params) + v := u.GetMethodParamInt("GetValue", "timeout", 1) assert.Equal(t, int64(3), v) @@ -259,7 +277,10 @@ func TestURLGetMethodParamInt(t *testing.T) { func TestURLGetMethodParam(t *testing.T) { params := url.Values{} params.Set("methods.GetValue.timeout", "3s") - u := URL{baseUrl: baseUrl{params: params}} + + u := URL{} + u.SetParams(params) + v := u.GetMethodParam("GetValue", "timeout", "1s") assert.Equal(t, "3s", v) @@ -271,7 +292,10 @@ func TestURLGetMethodParam(t *testing.T) { func TestURLGetMethodParamBool(t *testing.T) { params := url.Values{} params.Set("methods.GetValue.async", "true") - u := URL{baseUrl: baseUrl{params: params}} + + u := URL{} + u.SetParams(params) + v := u.GetMethodParamBool("GetValue", "async", false) assert.Equal(t, true, v) diff --git a/config_center/apollo/listener.go b/config_center/apollo/listener.go index ace5ed0268..44d325582f 100644 --- a/config_center/apollo/listener.go +++ b/config_center/apollo/listener.go @@ -36,7 +36,7 @@ type apolloListener struct { // nolint func newApolloListener() *apolloListener { return &apolloListener{ - listeners: make(map[config_center.ConfigurationListener]struct{}, 0), + listeners: make(map[config_center.ConfigurationListener]struct{}), } } diff --git a/filter/filter_impl/tps/tps_limiter_method_service_test.go b/filter/filter_impl/tps/tps_limiter_method_service_test.go index a70287eabd..4ff0a232e4 100644 --- a/filter/filter_impl/tps/tps_limiter_method_service_test.go +++ b/filter/filter_impl/tps/tps_limiter_method_service_test.go @@ -113,7 +113,7 @@ func TestMethodServiceTpsLimiterImplIsAllowableMethodLevelOverride(t *testing.T) func TestMethodServiceTpsLimiterImplIsAllowableBothMethodAndService(t *testing.T) { methodName := "hello3" methodConfigPrefix := "methods." + methodName + "." - invoc := invocation.NewRPCInvocation(methodName, []interface{}{"OK"}, make(map[string]interface{}, 0)) + invoc := invocation.NewRPCInvocation(methodName, []interface{}{"OK"}, make(map[string]interface{})) ctrl := gomock.NewController(t) defer ctrl.Finish() diff --git a/remoting/getty/listener_test.go b/remoting/getty/listener_test.go index 956ecf9849..2700ed8cd8 100644 --- a/remoting/getty/listener_test.go +++ b/remoting/getty/listener_test.go @@ -23,14 +23,14 @@ import ( ) import ( + "github.com/opentracing/opentracing-go" + "github.com/opentracing/opentracing-go/mocktracer" "github.com/stretchr/testify/assert" ) import ( "github.com/apache/dubbo-go/common/constant" "github.com/apache/dubbo-go/protocol/invocation" - "github.com/opentracing/opentracing-go" - "github.com/opentracing/opentracing-go/mocktracer" ) // test rebuild the ctx @@ -63,7 +63,7 @@ func TestRebuildCtx(t *testing.T) { // Once we decided to transfer more context's key-value, we should change this. // now we only support rebuild the tracing context func rebuildCtx(inv *invocation.RPCInvocation) context.Context { - ctx := context.WithValue(context.Background(), "attachment", inv.Attachments()) + ctx := context.WithValue(context.Background(), constant.DubboCtxKey("attachment"), inv.Attachments()) // actually, if user do not use any opentracing framework, the err will not be nil. spanCtx, err := opentracing.GlobalTracer().Extract(opentracing.TextMap, From b5784d263fc8c599965a6ea788033ff206e951b2 Mon Sep 17 00:00:00 2001 From: LaurenceLiZhixin <382673304@qq.com> Date: Mon, 4 Jan 2021 17:07:50 +0800 Subject: [PATCH 27/39] fix: fix err --- common/constant/key.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/constant/key.go b/common/constant/key.go index 6b754a23fb..9df6585bc0 100644 --- a/common/constant/key.go +++ b/common/constant/key.go @@ -244,7 +244,7 @@ const ( // HEALTH_ROUTE_ENABLED_KEY defines if use health router HEALTH_ROUTE_ENABLED_KEY = "health.route.enabled" // AttachmentKey in context in invoker - AttachmentKey = AttachmentCtxKey("attachment") + AttachmentKey = "attachment" ) const ( From e5bee952fa7aad8cc4aecf0e87ce0addf78df1af Mon Sep 17 00:00:00 2001 From: LaurenceLiZhixin <382673304@qq.com> Date: Thu, 7 Jan 2021 19:17:39 +0800 Subject: [PATCH 28/39] fix: lint --- cluster/router/conncheck/conn_check_route_test.go | 1 - cluster/router/conncheck/conn_health_check_test.go | 1 - protocol/dubbo/dubbo_codec.go | 2 +- protocol/grpc/protoc-gen-dubbo/main.go | 2 +- remoting/getty/dubbo_codec_for_test.go | 2 +- remoting/getty/listener.go | 4 ++-- 6 files changed, 5 insertions(+), 7 deletions(-) diff --git a/cluster/router/conncheck/conn_check_route_test.go b/cluster/router/conncheck/conn_check_route_test.go index 5277b0870b..edbc2cbeac 100644 --- a/cluster/router/conncheck/conn_check_route_test.go +++ b/cluster/router/conncheck/conn_check_route_test.go @@ -73,7 +73,6 @@ func TestConnCheckRouterRoute(t *testing.T) { // now invoker3 is healthy assert.True(t, len(res.ToArray()) == 1) - invoker2 = NewMockInvoker(url2) // check blacklist remove protocol.RemoveInvokerUnhealthyStatus(invoker1) diff --git a/cluster/router/conncheck/conn_health_check_test.go b/cluster/router/conncheck/conn_health_check_test.go index 7544014972..44d148e1b8 100644 --- a/cluster/router/conncheck/conn_health_check_test.go +++ b/cluster/router/conncheck/conn_health_check_test.go @@ -46,7 +46,6 @@ func TestDefaultConnCheckerIsHealthy(t *testing.T) { invoker = NewMockInvoker(url) cc = NewDefaultConnChecker(url).(*DefaultConnChecker) - healthy = cc.IsConnHealthy(invoker) // add to black list protocol.SetInvokerUnhealthyStatus(invoker) assert.False(t, cc.IsConnHealthy(invoker)) diff --git a/protocol/dubbo/dubbo_codec.go b/protocol/dubbo/dubbo_codec.go index f92da4aa7f..21376c3145 100644 --- a/protocol/dubbo/dubbo_codec.go +++ b/protocol/dubbo/dubbo_codec.go @@ -105,7 +105,7 @@ func (c *DubboCodec) EncodeRequest(request *remoting.Request) (*bytes.Buffer, er return pkg.Marshal() } -// encode heartbeart request +// encode heartbeat request func (c *DubboCodec) encodeHeartbeartReqeust(request *remoting.Request) (*bytes.Buffer, error) { header := impl.DubboHeader{ Type: impl.PackageHeartbeat, diff --git a/protocol/grpc/protoc-gen-dubbo/main.go b/protocol/grpc/protoc-gen-dubbo/main.go index fbcfa6f9d4..fe3e38dddd 100644 --- a/protocol/grpc/protoc-gen-dubbo/main.go +++ b/protocol/grpc/protoc-gen-dubbo/main.go @@ -43,7 +43,7 @@ func main() { g.Error(err, "reading input") } - if err := proto.Unmarshal(data, g.Request); err != nil { + if err = proto.Unmarshal(data, g.Request); err != nil { g.Error(err, "parsing input proto") } diff --git a/remoting/getty/dubbo_codec_for_test.go b/remoting/getty/dubbo_codec_for_test.go index be6d9db07c..9afc18a9aa 100644 --- a/remoting/getty/dubbo_codec_for_test.go +++ b/remoting/getty/dubbo_codec_for_test.go @@ -99,7 +99,7 @@ func (c *DubboTestCodec) EncodeRequest(request *remoting.Request) (*bytes.Buffer return pkg.Marshal() } -// encode heartbeart request +// encode heartbeat request func (c *DubboTestCodec) encodeHeartbeartReqeust(request *remoting.Request) (*bytes.Buffer, error) { header := impl.DubboHeader{ Type: impl.PackageHeartbeat, diff --git a/remoting/getty/listener.go b/remoting/getty/listener.go index b2f7790f2f..a07726e5a6 100644 --- a/remoting/getty/listener.go +++ b/remoting/getty/listener.go @@ -101,7 +101,7 @@ func (h *RpcClientHandler) OnMessage(session getty.Session, pkg interface{}) { logger.Errorf("illegal package") return } - // get heartbeart request from server + // get heartbeat request from server if result.IsRequest { req := result.Result.(*remoting.Request) if req.Event { @@ -252,7 +252,7 @@ func (h *RpcServerHandler) OnMessage(session getty.Session, pkg interface{}) { res.Handle() return } - logger.Errorf("illegal package but not heartbeart. {%#v}", pkg) + logger.Errorf("illegal package but not heartbeat. {%#v}", pkg) return } req := decodeResult.Result.(*remoting.Request) From 84bfb9d231198190384a4c69bf3c02c01f66eb3a Mon Sep 17 00:00:00 2001 From: LaurenceLiZhixin <382673304@qq.com> Date: Thu, 7 Jan 2021 19:37:14 +0800 Subject: [PATCH 29/39] fix: lint --- common/proxy/proxy_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/proxy/proxy_test.go b/common/proxy/proxy_test.go index cbac1f3bb4..d91db48412 100644 --- a/common/proxy/proxy_test.go +++ b/common/proxy/proxy_test.go @@ -135,8 +135,8 @@ func TestProxyImplementForContext(t *testing.T) { attahments1 := make(map[string]interface{}, 4) attahments1["k1"] = "v1" attahments1["k2"] = "v2" - context := context.WithValue(context.Background(), constant.AttachmentKey, attahments1) - r, err := p.Get().(*TestService).MethodSix(context, "xxx") + ctx := context.WithValue(context.Background(), constant.AttachmentKey, attahments1) + r, err := p.Get().(*TestService).MethodSix(ctx, "xxx") v1 := r.(map[string]interface{}) assert.NoError(t, err) assert.Equal(t, v1["TestProxyInvoker"], "TestProxyInvokerValue") From a15546aa26d82e718c6781c06adedc639776787f Mon Sep 17 00:00:00 2001 From: LaurenceLiZhixin <382673304@qq.com> Date: Thu, 7 Jan 2021 19:48:02 +0800 Subject: [PATCH 30/39] fix: lint --- common/constant/key.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/constant/key.go b/common/constant/key.go index 9df6585bc0..51d86aafb8 100644 --- a/common/constant/key.go +++ b/common/constant/key.go @@ -244,7 +244,7 @@ const ( // HEALTH_ROUTE_ENABLED_KEY defines if use health router HEALTH_ROUTE_ENABLED_KEY = "health.route.enabled" // AttachmentKey in context in invoker - AttachmentKey = "attachment" + AttachmentKey = DubboCtxKey("attachment") ) const ( From ed0b174666700a58af70e75a646be08885b415b6 Mon Sep 17 00:00:00 2001 From: LaurenceLiZhixin <382673304@qq.com> Date: Sun, 17 Jan 2021 17:14:01 +0800 Subject: [PATCH 31/39] fix --- protocol/rpc_status.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocol/rpc_status.go b/protocol/rpc_status.go index 5f6225ba7c..60df2e8cb1 100644 --- a/protocol/rpc_status.go +++ b/protocol/rpc_status.go @@ -245,7 +245,7 @@ func GetAndRefreshState() bool { } // TryRefreshBlackList start 3 gr to check at most block=16 invokers in black list -// if is available remove from black list +// if target invoker is available, then remove it from black list func TryRefreshBlackList() { if atomic.CompareAndSwapInt32(&blackListRefreshing, 0, 1) { wg := sync.WaitGroup{} From be89b70cf0e63f054ff4b02bc258b51f998fafab Mon Sep 17 00:00:00 2001 From: LaurenceLiZhixin <382673304@qq.com> Date: Sun, 17 Jan 2021 17:27:11 +0800 Subject: [PATCH 32/39] fix: chinglish --- cluster/cluster_impl/base_cluster_invoker.go | 2 +- common/extension/conn_checker.go | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/cluster/cluster_impl/base_cluster_invoker.go b/cluster/cluster_impl/base_cluster_invoker.go index a2d65291f4..e76b5bf6f7 100644 --- a/cluster/cluster_impl/base_cluster_invoker.go +++ b/cluster/cluster_impl/base_cluster_invoker.go @@ -136,7 +136,7 @@ func (invoker *baseClusterInvoker) doSelectInvoker(lb cluster.LoadBalance, invoc selectedInvoker := lb.Select(invokers, invocation) - //judge to if the selectedInvoker is invoked and available + //judge if the selected Invoker is invoked and available if (!selectedInvoker.IsAvailable() && invoker.availablecheck) || isInvoked(selectedInvoker, invoked) { protocol.SetInvokerUnhealthyStatus(selectedInvoker) otherInvokers := getOtherInvokers(invokers, selectedInvoker) diff --git a/common/extension/conn_checker.go b/common/extension/conn_checker.go index 99add91f80..fbd9e34b23 100644 --- a/common/extension/conn_checker.go +++ b/common/extension/conn_checker.go @@ -33,7 +33,8 @@ func SetConnChecker(name string, fcn func(_ *common.URL) router.ConnChecker) { // GetHealthChecker gets the HealthChecker with @name func GetConnChecker(name string, url *common.URL) router.ConnChecker { - if connCheckers[name] == nil { + f, ok := connCheckers[name] + if !ok || f == nil { panic("connCheckers for " + name + " is not existing, make sure you have import the package.") } return connCheckers[name](url) From add1618efe596400b1e24b04542f9aa1043bd0ee Mon Sep 17 00:00:00 2001 From: LaurenceLiZhixin <382673304@qq.com> Date: Sun, 17 Jan 2021 17:35:53 +0800 Subject: [PATCH 33/39] fix: conflict --- common/proxy/proxy_test.go | 8 -------- go.mod | 2 ++ 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/common/proxy/proxy_test.go b/common/proxy/proxy_test.go index 9ce36835c8..c335bf6783 100644 --- a/common/proxy/proxy_test.go +++ b/common/proxy/proxy_test.go @@ -132,19 +132,11 @@ func TestProxyImplementForContext(t *testing.T) { p := NewProxy(invoker, nil, map[string]string{constant.ASYNC_KEY: "false"}) s := &TestService{} p.Implement(s) -<<<<<<< HEAD - attahments1 := make(map[string]interface{}, 4) - attahments1["k1"] = "v1" - attahments1["k2"] = "v2" - ctx := context.WithValue(context.Background(), constant.AttachmentKey, attahments1) - r, err := p.Get().(*TestService).MethodSix(ctx, "xxx") -======= attachments1 := make(map[string]interface{}, 4) attachments1["k1"] = "v1" attachments1["k2"] = "v2" context := context.WithValue(context.Background(), constant.AttachmentKey, attachments1) r, err := p.Get().(*TestService).MethodSix(context, "xxx") ->>>>>>> develop v1 := r.(map[string]interface{}) assert.NoError(t, err) assert.Equal(t, v1["TestProxyInvoker"], "TestProxyInvokerValue") diff --git a/go.mod b/go.mod index 18d85a650f..ac83a94bcf 100644 --- a/go.mod +++ b/go.mod @@ -1,5 +1,7 @@ module github.com/apache/dubbo-go +go 1.15 + require ( github.com/NYTimes/gziphandler v1.1.1 // indirect github.com/RoaringBitmap/roaring v0.5.5 From 4f3d161cf36cc2155e05faddf54b9f1ed5553656 Mon Sep 17 00:00:00 2001 From: LaurenceLiZhixin <382673304@qq.com> Date: Fri, 22 Jan 2021 16:58:50 +0800 Subject: [PATCH 34/39] fix: delete logic of invocation get invoker --- cluster/cluster_impl/base_cluster_invoker.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cluster/cluster_impl/base_cluster_invoker.go b/cluster/cluster_impl/base_cluster_invoker.go index e76b5bf6f7..d58a2de57e 100644 --- a/cluster/cluster_impl/base_cluster_invoker.go +++ b/cluster/cluster_impl/base_cluster_invoker.go @@ -121,7 +121,6 @@ func (invoker *baseClusterInvoker) doSelect(lb cluster.LoadBalance, invocation p func (invoker *baseClusterInvoker) doSelectInvoker(lb cluster.LoadBalance, invocation protocol.Invocation, invokers []protocol.Invoker, invoked []protocol.Invoker) protocol.Invoker { if len(invokers) == 0 { - logger.Errorf("the invokers of %s is nil. ", invocation.Invoker().GetUrl().ServiceKey()) return nil } go protocol.TryRefreshBlackList() @@ -130,7 +129,7 @@ func (invoker *baseClusterInvoker) doSelectInvoker(lb cluster.LoadBalance, invoc return invokers[0] } protocol.SetInvokerUnhealthyStatus(invokers[0]) - logger.Errorf("the invokers of %s is nil. ", invocation.Invoker().GetUrl().ServiceKey()) + logger.Errorf("the invokers of %s is nil. ", invokers[0].GetUrl().ServiceKey()) return nil } From 2c2c35fb9570c3ccaa9944ae6797dc5707ad88f3 Mon Sep 17 00:00:00 2001 From: LaurenceLiZhixin <382673304@qq.com> Date: Sun, 24 Jan 2021 12:47:51 +0800 Subject: [PATCH 35/39] fix: split import block --- cluster/router/conncheck/conn_check_route_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cluster/router/conncheck/conn_check_route_test.go b/cluster/router/conncheck/conn_check_route_test.go index edbc2cbeac..80ec1c8ea9 100644 --- a/cluster/router/conncheck/conn_check_route_test.go +++ b/cluster/router/conncheck/conn_check_route_test.go @@ -19,12 +19,11 @@ package conncheck import ( "fmt" - "github.com/apache/dubbo-go/protocol/mock" - "github.com/golang/mock/gomock" "testing" ) import ( + "github.com/golang/mock/gomock" "github.com/stretchr/testify/assert" ) @@ -35,6 +34,7 @@ import ( "github.com/apache/dubbo-go/common" "github.com/apache/dubbo-go/protocol" "github.com/apache/dubbo-go/protocol/invocation" + "github.com/apache/dubbo-go/protocol/mock" ) const ( From 25c1e44a02348a18b3e346d4798082ef9b3f3f4b Mon Sep 17 00:00:00 2001 From: LaurenceLiZhixin <382673304@qq.com> Date: Tue, 26 Jan 2021 19:27:14 +0800 Subject: [PATCH 36/39] fix: add log to show blacklist changes --- protocol/rpc_status.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/protocol/rpc_status.go b/protocol/rpc_status.go index 60df2e8cb1..ee4d74ffee 100644 --- a/protocol/rpc_status.go +++ b/protocol/rpc_status.go @@ -210,12 +210,14 @@ func GetInvokerHealthyStatus(invoker Invoker) bool { // SetInvokerUnhealthyStatus add target invoker to black list func SetInvokerUnhealthyStatus(invoker Invoker) { invokerBlackList.Store(invoker.GetUrl().Key(), invoker) + logger.Info("Add invoker ip = ", invoker.GetUrl().Location, " to black list") blackListCacheDirty.Store(true) } // RemoveInvokerUnhealthyStatus remove unhealthy status of target invoker from blacklist func RemoveInvokerUnhealthyStatus(invoker Invoker) { invokerBlackList.Delete(invoker.GetUrl().Key()) + logger.Info("Remove invoker ip = ", invoker.GetUrl().Location, " from black list") blackListCacheDirty.Store(true) } @@ -235,6 +237,7 @@ func GetBlackListInvokers(blockSize int) []Invoker { // RemoveUrlKeyUnhealthyStatus called when event of provider unregister, delete from black list func RemoveUrlKeyUnhealthyStatus(key string) { invokerBlackList.Delete(key) + logger.Info("Remove invoker key = ", key, " from black list") blackListCacheDirty.Store(true) } From e5d53ca47d4ddf664893074b2d854a61530780ca Mon Sep 17 00:00:00 2001 From: LaurenceLiZhixin <382673304@qq.com> Date: Wed, 3 Feb 2021 19:29:14 +0800 Subject: [PATCH 37/39] fix: change notify chain --- cluster/router/chain/chain_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cluster/router/chain/chain_test.go b/cluster/router/chain/chain_test.go index d56a1f4416..779f4c7c00 100644 --- a/cluster/router/chain/chain_test.go +++ b/cluster/router/chain/chain_test.go @@ -150,8 +150,7 @@ conditions: factory := extension.GetRouterFactory(url.Protocol) notify := make(chan struct{}) go func() { - for { - <-notify + for range notify { } }() r, err := factory.NewPriorityRouter(url, notify) From edd99f59ecf7b7b8b43de01ad29b04c59a91ba53 Mon Sep 17 00:00:00 2001 From: LaurenceLiZhixin <382673304@qq.com> Date: Wed, 3 Feb 2021 19:33:01 +0800 Subject: [PATCH 38/39] fix: range --- cluster/router/condition/app_router_test.go | 9 ++--- cluster/router/condition/factory_test.go | 36 +++++++------------ cluster/router/condition/router_test.go | 3 +- .../router/conncheck/conn_check_route_test.go | 3 +- .../healthcheck/health_check_route_test.go | 6 ++-- cluster/router/tag/factory_test.go | 3 +- cluster/router/tag/tag_router_test.go | 21 ++++------- 7 files changed, 27 insertions(+), 54 deletions(-) diff --git a/cluster/router/condition/app_router_test.go b/cluster/router/condition/app_router_test.go index b4c3056f8a..5fb776a44b 100644 --- a/cluster/router/condition/app_router_test.go +++ b/cluster/router/condition/app_router_test.go @@ -83,8 +83,7 @@ conditions: appRouteURL := getAppRouteURL(routerKey) notify := make(chan struct{}) go func() { - for { - <-notify + for range notify { } }() appRouter, err := NewAppRouter(appRouteURL, notify) @@ -140,8 +139,7 @@ conditions: appRouteURL := getAppRouteURL(routerKey) notify := make(chan struct{}) go func() { - for { - <-notify + for range notify { } }() appRouter, err := NewAppRouter(appRouteURL, notify) @@ -188,8 +186,7 @@ conditions: appRouteURL := getAppRouteURL(routerKey) notify := make(chan struct{}) go func() { - for { - <-notify + for range notify { } }() appRouter, err := NewAppRouter(appRouteURL, notify) diff --git a/cluster/router/condition/factory_test.go b/cluster/router/condition/factory_test.go index efbc4057bf..e08016d13e 100644 --- a/cluster/router/condition/factory_test.go +++ b/cluster/router/condition/factory_test.go @@ -134,8 +134,7 @@ func TestRoute_matchWhen(t *testing.T) { rule := base64.URLEncoding.EncodeToString([]byte("=> host = 1.2.3.4")) notify := make(chan struct{}) go func() { - for { - <-notify + for range notify { } }() router, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule), notify) @@ -171,8 +170,7 @@ func TestRoute_matchWhen(t *testing.T) { func TestRoute_matchFilter(t *testing.T) { notify := make(chan struct{}) go func() { - for { - <-notify + for range notify { } }() localIP := common.GetLocalIp() @@ -212,8 +210,7 @@ func TestRoute_matchFilter(t *testing.T) { func TestRoute_methodRoute(t *testing.T) { notify := make(chan struct{}) go func() { - for { - <-notify + for range notify { } }() inv := invocation.NewRPCInvocationWithOptions(invocation.WithMethodName("getFoo"), invocation.WithParameterTypes([]reflect.Type{}), invocation.WithArguments([]interface{}{})) @@ -241,8 +238,7 @@ func TestRoute_methodRoute(t *testing.T) { func TestRoute_ReturnFalse(t *testing.T) { notify := make(chan struct{}) go func() { - for { - <-notify + for range notify { } }() url, _ := common.NewURL("") @@ -259,8 +255,7 @@ func TestRoute_ReturnFalse(t *testing.T) { func TestRoute_ReturnEmpty(t *testing.T) { notify := make(chan struct{}) go func() { - for { - <-notify + for range notify { } }() localIP := common.GetLocalIp() @@ -277,8 +272,7 @@ func TestRoute_ReturnEmpty(t *testing.T) { func TestRoute_ReturnAll(t *testing.T) { notify := make(chan struct{}) go func() { - for { - <-notify + for range notify { } }() localIP := common.GetLocalIp() @@ -303,8 +297,7 @@ func TestRoute_HostFilter(t *testing.T) { url3, _ := common.NewURL(fmt.Sprintf(factoryDubboFormat, localIP)) notify := make(chan struct{}) go func() { - for { - <-notify + for range notify { } }() invoker1 := NewMockInvoker(url1, 1) @@ -324,8 +317,7 @@ func TestRoute_HostFilter(t *testing.T) { func TestRoute_Empty_HostFilter(t *testing.T) { notify := make(chan struct{}) go func() { - for { - <-notify + for range notify { } }() localIP := common.GetLocalIp() @@ -349,8 +341,7 @@ func TestRoute_Empty_HostFilter(t *testing.T) { func TestRoute_False_HostFilter(t *testing.T) { notify := make(chan struct{}) go func() { - for { - <-notify + for range notify { } }() localIP := common.GetLocalIp() @@ -374,8 +365,7 @@ func TestRoute_False_HostFilter(t *testing.T) { func TestRoute_Placeholder(t *testing.T) { notify := make(chan struct{}) go func() { - for { - <-notify + for range notify { } }() localIP := common.GetLocalIp() @@ -399,8 +389,7 @@ func TestRoute_Placeholder(t *testing.T) { func TestRoute_NoForce(t *testing.T) { notify := make(chan struct{}) go func() { - for { - <-notify + for range notify { } }() localIP := common.GetLocalIp() @@ -422,8 +411,7 @@ func TestRoute_NoForce(t *testing.T) { func TestRoute_Force(t *testing.T) { notify := make(chan struct{}) go func() { - for { - <-notify + for range notify { } }() localIP := common.GetLocalIp() diff --git a/cluster/router/condition/router_test.go b/cluster/router/condition/router_test.go index 15bf76f085..2895703dbc 100644 --- a/cluster/router/condition/router_test.go +++ b/cluster/router/condition/router_test.go @@ -60,8 +60,7 @@ func TestParseRule(t *testing.T) { func TestNewConditionRouter(t *testing.T) { notify := make(chan struct{}) go func() { - for { - <-notify + for range notify { } }() url, _ := common.NewURL(`condition://0.0.0.0:?application=mock-app&category=routers&force=true&priority=1&router=condition&rule=YSAmIGMgPT4gYiAmIGQ%3D`) diff --git a/cluster/router/conncheck/conn_check_route_test.go b/cluster/router/conncheck/conn_check_route_test.go index 80ec1c8ea9..fec733167f 100644 --- a/cluster/router/conncheck/conn_check_route_test.go +++ b/cluster/router/conncheck/conn_check_route_test.go @@ -50,8 +50,7 @@ func TestConnCheckRouterRoute(t *testing.T) { defer protocol.CleanAllStatus() notify := make(chan struct{}) go func() { - for { - <-notify + for range notify { } }() consumerURL, _ := common.NewURL(connCheck1001URL) diff --git a/cluster/router/healthcheck/health_check_route_test.go b/cluster/router/healthcheck/health_check_route_test.go index 1d44eb1a35..f499c85c09 100644 --- a/cluster/router/healthcheck/health_check_route_test.go +++ b/cluster/router/healthcheck/health_check_route_test.go @@ -51,8 +51,7 @@ func TestHealthCheckRouterRoute(t *testing.T) { defer protocol.CleanAllStatus() notify := make(chan struct{}) go func() { - for { - <-notify + for range notify { } }() consumerURL, _ := common.NewURL(healthCheck1001URL) @@ -120,8 +119,7 @@ func TestNewHealthCheckRouter(t *testing.T) { defer protocol.CleanAllStatus() notify := make(chan struct{}) go func() { - for { - <-notify + for range notify { } }() url, _ := common.NewURL(fmt.Sprintf(healthCheckDubboUrlFormat, healthCheckDubbo1010IP)) diff --git a/cluster/router/tag/factory_test.go b/cluster/router/tag/factory_test.go index ea5ff63fa0..2a8eac20ba 100644 --- a/cluster/router/tag/factory_test.go +++ b/cluster/router/tag/factory_test.go @@ -41,8 +41,7 @@ func TestTagRouterFactoryNewRouter(t *testing.T) { factory := NewTagRouterFactory() notify := make(chan struct{}) go func() { - for { - <-notify + for range notify { } }() tagRouter, e := factory.NewPriorityRouter(u1, notify) diff --git a/cluster/router/tag/tag_router_test.go b/cluster/router/tag/tag_router_test.go index 8dccc3420a..efee5bd684 100644 --- a/cluster/router/tag/tag_router_test.go +++ b/cluster/router/tag/tag_router_test.go @@ -121,8 +121,7 @@ func TestTagRouterPriority(t *testing.T) { u1, err := common.NewURL(tagRouterTestUserConsumerTag) notify := make(chan struct{}) go func() { - for { - <-notify + for range notify { } }() assert.Nil(t, err) @@ -135,8 +134,7 @@ func TestTagRouterPriority(t *testing.T) { func TestTagRouterRouteForce(t *testing.T) { notify := make(chan struct{}) go func() { - for { - <-notify + for range notify { } }() u1, e1 := common.NewURL(tagRouterTestUserConsumerTag) @@ -175,8 +173,7 @@ func TestTagRouterRouteNoForce(t *testing.T) { assert.Nil(t, e1) notify := make(chan struct{}) go func() { - for { - <-notify + for range notify { } }() tagRouter, e := NewTagRouter(u1, notify) @@ -244,8 +241,7 @@ func TestRouteBeijingInvoker(t *testing.T) { url, _ := common.NewURL(tagRouterTestBeijingUrl) notify := make(chan struct{}) go func() { - for { - <-notify + for range notify { } }() tagRouter, _ := NewTagRouter(url, notify) @@ -326,8 +322,7 @@ tags: notify := make(chan struct{}) go func() { - for { - <-notify + for range notify { } }() tagRouter, err := NewTagRouter(url, notify) @@ -397,8 +392,7 @@ func TestProcess(t *testing.T) { assert.Nil(t, err) notify := make(chan struct{}) go func() { - for { - <-notify + for range notify { } }() tagRouter, e := NewTagRouter(u1, notify) @@ -420,8 +414,7 @@ tags: addresses: [192.168.1.3, 192.168.1.4] ` go func() { - for { - <-notify + for range notify { } }() tagRouter.Process(&config_center.ConfigChangeEvent{Value: testYML, ConfigType: remoting.EventTypeAdd}) From 93094ed554cb608b7265f402a18d77639b4bfaa6 Mon Sep 17 00:00:00 2001 From: LaurenceLiZhixin <382673304@qq.com> Date: Fri, 5 Feb 2021 17:34:39 +0800 Subject: [PATCH 39/39] fix: cr --- cluster/cluster_impl/base_cluster_invoker.go | 11 ++++++----- protocol/rpc_status.go | 6 ++---- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/cluster/cluster_impl/base_cluster_invoker.go b/cluster/cluster_impl/base_cluster_invoker.go index d58a2de57e..0d39bff13e 100644 --- a/cluster/cluster_impl/base_cluster_invoker.go +++ b/cluster/cluster_impl/base_cluster_invoker.go @@ -143,8 +143,7 @@ func (invoker *baseClusterInvoker) doSelectInvoker(lb cluster.LoadBalance, invoc for i := 0; i < 3; i++ { if len(otherInvokers) == 0 { // no other ivk to reselect, return to fallback - logger.Errorf("all %d invokers is unavailable for %s.", len(invokers), selectedInvoker.GetUrl().String()) - return nil + break } reselectedInvoker := lb.Select(otherInvokers, invocation) if isInvoked(reselectedInvoker, invoked) { @@ -158,11 +157,13 @@ func (invoker *baseClusterInvoker) doSelectInvoker(lb cluster.LoadBalance, invoc otherInvokers = getOtherInvokers(otherInvokers, reselectedInvoker) continue } - selectedInvoker = reselectedInvoker - break + return reselectedInvoker } + } else { + return selectedInvoker } - return selectedInvoker + logger.Errorf("all %d invokers is unavailable for %s.", len(invokers), selectedInvoker.GetUrl().String()) + return nil } func (invoker *baseClusterInvoker) Invoke(ctx context.Context, invocation protocol.Invocation) protocol.Result { diff --git a/protocol/rpc_status.go b/protocol/rpc_status.go index ee4d74ffee..8fc5ddd76e 100644 --- a/protocol/rpc_status.go +++ b/protocol/rpc_status.go @@ -264,10 +264,8 @@ func TryRefreshBlackList() { go func(ivks []Invoker, i int) { defer wg.Done() for j, _ := range ivks { - if j%3-i == 0 { - if ivks[j].(Invoker).IsAvailable() { - RemoveInvokerUnhealthyStatus(ivks[i]) - } + if j%3-i == 0 && ivks[j].(Invoker).IsAvailable() { + RemoveInvokerUnhealthyStatus(ivks[i]) } } }(ivks, i)