diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 3eb1ec055f18f29a7886e01c24e10c97f88fb1e8..9daa31016dca8890ef8ce64396e0f6ebe9a41462 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,4 +1,5 @@ -<!-- Thanks for sending a pull request! +<!-- Thanks for sending a pull request! +Read https://github.com/apache/dubbo-go/blob/master/contributing.md before commit pull request. --> **What this PR does**: diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index 732e426fec2a7b3efa8899ee6b1536e660b142bb..7875ca65968a430e03583f91a82784118963e4bc 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -19,10 +19,6 @@ jobs: os: - ubuntu-latest - env: - DING_TOKEN: "6374f1bf8d4f23cde81d4a4b8c1f0bc98cc92b5151ca938ab938d3d7f4230fc4" - DING_SIGN: "SECa98677289194bb0e5caec3051301d06515750ff1bd2f932a4704298afb2e0ae6" - steps: - name: Set up Go 1.x @@ -68,45 +64,4 @@ jobs: chmod +x integrate_test.sh && ./integrate_test.sh - name: Coverage - run: bash <(curl -s https://codecov.io/bash) - - # Because the contexts of push and PR are different, there are two Notify. - # Notifications are triggered only in the apache/dubbo-go repository. - - name: DingTalk Message Notify only Push - uses: zcong1993/actions-ding@v3.0.1 - # Whether job is successful or not, always () is always true. - if: | - always() && - github.event_name == 'push' && - github.repository == 'apache/dubbo-go' - with: - # DingDing bot token - dingToken: ${{ env.DING_TOKEN }} - secret: ${{ env.DING_SIGN }} - # Post Body to send - body: | - { - "msgtype": "markdown", - "markdown": { - "title": "Github Actions", - "text": "## Github Actions \n - name: CI \n - repository: ${{ github.repository }} \n - trigger: ${{ github.actor }} \n - event: ${{ github.event_name }} \n - ref: ${{ github.ref }} \n - status: [${{ job.status }}](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}) \n - environment: ${{ runner.os }} \n - SHA: [${{ github.sha }}](${{ github.event.compare }})" - } - } - - - name: DingTalk Message Notify only PR - uses: zcong1993/actions-ding@v3.0.1 - if: | - always() && - github.event_name == 'pull_request' && - github.repository == 'apache/dubbo-go' - with: - dingToken: ${{ env.DING_TOKEN }} - secret: ${{ env.DING_SIGN }} - body: | - { - "msgtype": "markdown", - "markdown": { - "title": "Github Actions", - "text": "## Github Actions \n - name: CI \n - repository: ${{ github.repository }} \n - pr_title: ${{ github.event.pull_request.title }} \n - trigger: ${{ github.actor }} \n - event: ${{ github.event_name }} \n - ref: [${{ github.ref }}](${{ github.event.pull_request._links.html.href }}) \n - status: [${{ job.status }}](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}) \n - environment: ${{ runner.os }} \n > SHA: [${{ github.sha }}](${{ github.event.pull_request._links.html.href }})" - } - } + run: bash <(curl -s https://codecov.io/bash) \ No newline at end of file diff --git a/before_ut.bat b/before_ut.bat index 7f5cf50e900955f784552221569d9caf414274d4..b8d72e4a873ef4ff9653c6f16ebd4378ce1ee172 100644 --- a/before_ut.bat +++ b/before_ut.bat @@ -36,8 +36,8 @@ xcopy /f "%zkJar%" "cluster/router/chain/zookeeper-4unittest/contrib/fatjar/" md cluster\router\condition\zookeeper-4unittest\contrib\fatjar xcopy /f "%zkJar%" "cluster/router/condition/zookeeper-4unittest/contrib/fatjar/" -mkdir -p cluster/router/tag/zookeeper-4unittest/contrib/fatjar -cp ${zkJar} cluster/router/tag/zookeeper-4unittest/contrib/fatjar +md cluster/router/tag/zookeeper-4unittest/contrib/fatjar +xcopy /f "%zkJar%" "cluster/router/tag/zookeeper-4unittest/contrib/fatjar/" md metadata\report\zookeeper\zookeeper-4unittest\contrib\fatjar xcopy /f "%zkJar%" "metadata/report/zookeeper/zookeeper-4unittest/contrib/fatjar/" \ No newline at end of file diff --git a/common/url.go b/common/url.go index 5a3e57406bf221a341d9a3ea120943144a35aca0..8297afdaad235cbd9a70b057e0f43db6c48dbf82 100644 --- a/common/url.go +++ b/common/url.go @@ -26,6 +26,7 @@ import ( "net/url" "strconv" "strings" + "sync" ) import ( @@ -77,10 +78,12 @@ func (t RoleType) Role() string { } type baseUrl struct { - Protocol string - Location string // ip+port - Ip string - Port string + Protocol string + 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 } @@ -393,16 +396,16 @@ func (c URL) Service() string { } // AddParam will add the key-value pair -// Not thread-safe -// think twice before using it. func (c *URL) AddParam(key string, value string) { + c.paramsLock.Lock() + defer c.paramsLock.Unlock() c.params.Add(key, value) } // AddParamAvoidNil will add key-value pair -// Not thread-safe -// think twice before using it. func (c *URL) AddParamAvoidNil(key string, value string) { + c.paramsLock.Lock() + defer c.paramsLock.Unlock() if c.params == nil { c.params = url.Values{} } @@ -411,16 +414,17 @@ func (c *URL) AddParamAvoidNil(key string, value string) { } // SetParam will put the key-value pair into url -// it's not thread safe. -// think twice before you want to use this method // usually it should only be invoked when you want to initialized an url func (c *URL) SetParam(key string, value string) { + c.paramsLock.Lock() + defer c.paramsLock.Unlock() c.params.Set(key, value) } // RangeParams will iterate the params -// it's not thread-safe func (c *URL) RangeParams(f func(key, value string) bool) { + c.paramsLock.RLock() + defer c.paramsLock.RUnlock() for k, v := range c.params { if !f(k, v[0]) { break @@ -430,6 +434,8 @@ func (c *URL) RangeParams(f func(key, value string) bool) { // GetParam gets value by key func (c URL) GetParam(s string, d string) string { + c.paramsLock.RLock() + defer c.paramsLock.RUnlock() r := c.params.Get(s) if len(r) == 0 { r = d diff --git a/protocol/dubbo/dubbo_invoker_test.go b/protocol/dubbo/dubbo_invoker_test.go index 4d32c29a222e8bb73486d664b2ed2e0038a4b3f5..c80f412ff0337c56cc146ff710e491579c425b95 100644 --- a/protocol/dubbo/dubbo_invoker_test.go +++ b/protocol/dubbo/dubbo_invoker_test.go @@ -89,15 +89,15 @@ func TestDubboInvokerInvoke(t *testing.T) { // destroy lock.Lock() + defer lock.Unlock() proto.Destroy() - lock.Unlock() } func InitTest(t *testing.T) (protocol.Protocol, common.URL) { hessian.RegisterPOJO(&User{}) - methods, err := common.ServiceMap.Register("", "dubbo", &UserProvider{}) + methods, err := common.ServiceMap.Register("com.ikurento.user.UserProvider", "dubbo", &UserProvider{}) assert.NoError(t, err) assert.Equal(t, "GetBigPkg,GetUser,GetUser0,GetUser1,GetUser2,GetUser3,GetUser4,GetUser5,GetUser6", methods) @@ -176,10 +176,9 @@ type ( // size:4801228 func (u *UserProvider) GetBigPkg(ctx context.Context, req []interface{}, rsp *User) error { argBuf := new(bytes.Buffer) - for i := 0; i < 400; i++ { + for i := 0; i < 800; i++ { // use chinese for test argBuf.WriteString("鍑婚紦鍏堕晽锛岃笂璺冪敤鍏点€傚湡鍥藉煄婕曪紝鎴戠嫭鍗楄銆備粠瀛欏瓙浠诧紝骞抽檲涓庡畫銆備笉鎴戜互褰掞紝蹇у績鏈夊俊銆傜埌灞呯埌澶勶紵鐖颁抚鍏堕┈锛熶簬浠ユ眰涔嬶紵浜庢灄涔嬩笅銆傛鐢熷闃旓紝涓庡瓙鎴愯銆傛墽瀛愪箣鎵嬶紝涓庡瓙鍋曡€併€備簬鍡熼様鍏紝涓嶆垜娲诲叜銆備簬鍡熸吹鍏紝涓嶆垜淇″叜銆�") - argBuf.WriteString("鍑婚紦鍏堕晽锛岃笂璺冪敤鍏点€傚湡鍥藉煄婕曪紝鎴戠嫭鍗楄銆備粠瀛欏瓙浠诧紝骞抽檲涓庡畫銆備笉鎴戜互褰掞紝蹇у績鏈夊俊銆傜埌灞呯埌澶勶紵鐖颁抚鍏堕┈锛熶簬浠ユ眰涔嬶紵浜庢灄涔嬩笅銆傛鐢熷闃旓紝涓庡瓙鎴愯銆傛墽瀛愪箣鎵嬶紝涓庡瓙鍋曡€併€備簬鍡熼様鍏紝涓嶆垜娲诲叜銆備簬鍡熸吹鍏紝涓嶆垜淇″叜銆�") } rsp.Id = argBuf.String() rsp.Name = argBuf.String() diff --git a/registry/consul/registry.go b/registry/consul/registry.go index c425c5ec20d36be02c00499340f13b13c9aa2655..b92e335fdb69f82210d2977789902eb6123201b8 100644 --- a/registry/consul/registry.go +++ b/registry/consul/registry.go @@ -36,7 +36,8 @@ import ( ) const ( - registryConnDelay = 3 + registryConnDelay = 3 + registryDestroyDefaultTimeout = time.Second * 3 ) func init() { @@ -187,5 +188,25 @@ func (r *consulRegistry) IsAvailable() bool { // Destroy consul registry center func (r *consulRegistry) Destroy() { + if r.URL != nil { + done := make(chan struct{}, 1) + go func() { + defer func() { + if e := recover(); e != nil { + logger.Errorf("consulRegistry destory with panic: %v", e) + } + done <- struct{}{} + }() + if err := r.UnRegister(*r.URL); err != nil { + logger.Errorf("consul registry unregister with err: %s", err.Error()) + } + }() + select { + case <-done: + logger.Infof("consulRegistry unregister done") + case <-time.After(registryDestroyDefaultTimeout): + logger.Errorf("consul unregister timeout") + } + } close(r.done) } diff --git a/registry/consul/registry_test.go b/registry/consul/registry_test.go index 94718f5ab657c198882f065a50e5d5a2c9d4bc6f..b300f7536ddf35f2a4d062900b1f3e4eda33f25d 100644 --- a/registry/consul/registry_test.go +++ b/registry/consul/registry_test.go @@ -55,3 +55,19 @@ func (suite *consulRegistryTestSuite) testSubscribe() { assert.NoError(suite.t, err) suite.listener = listener } + +func (suite *consulRegistryTestSuite) testDestroy() { + consumerRegistryUrl := newConsumerRegistryUrl(registryHost, registryPort) + consumerRegistry, _ := newConsulRegistry(consumerRegistryUrl) + consulRegistryImp := consumerRegistry.(*consulRegistry) + assert.True(suite.t, consulRegistryImp.IsAvailable()) + consulRegistryImp.Destroy() + assert.False(suite.t, consulRegistryImp.IsAvailable()) + + consumerRegistry, _ = newConsulRegistry(consumerRegistryUrl) + consulRegistryImp = consumerRegistry.(*consulRegistry) + consulRegistryImp.URL = nil + assert.True(suite.t, consulRegistryImp.IsAvailable()) + consulRegistryImp.Destroy() + assert.False(suite.t, consulRegistryImp.IsAvailable()) +} diff --git a/registry/consul/utils_test.go b/registry/consul/utils_test.go index 939352dc088faa2c32be8173d0aa6f4516dfe503..0e5bffe457b9e3317ff056c51e4f5a9633a429e6 100644 --- a/registry/consul/utils_test.go +++ b/registry/consul/utils_test.go @@ -163,6 +163,7 @@ func test1(t *testing.T) { suite.testListener(remoting.EventTypeAdd) suite.testUnregister() suite.testListener(remoting.EventTypeDel) + suite.testDestroy() } // subscribe -> register -> unregister @@ -183,6 +184,7 @@ func test2(t *testing.T) { suite.testListener(remoting.EventTypeAdd) suite.testUnregister() suite.testListener(remoting.EventTypeDel) + suite.testDestroy() } func TestConsulRegistry(t *testing.T) { diff --git a/registry/nacos/registry.go b/registry/nacos/registry.go index 411090820c7682ab9c3b5576ea8ad5207c2c899f..757474455b7e5df6e5fb454228cdcb551b6a3a0e 100644 --- a/registry/nacos/registry.go +++ b/registry/nacos/registry.go @@ -288,6 +288,7 @@ func getNacosConfig(url *common.URL) (map[string]interface{}, error) { clientConfig.CacheDir = url.GetParam(constant.NACOS_CACHE_DIR_KEY, "") clientConfig.LogDir = url.GetParam(constant.NACOS_LOG_DIR_KEY, "") clientConfig.Endpoint = url.GetParam(constant.NACOS_ENDPOINT, "") + clientConfig.NamespaceId = url.GetParam(constant.NACOS_NAMESPACE_ID, "") clientConfig.NotLoadCacheAtStart = true configMap["clientConfig"] = clientConfig diff --git a/remoting/getty/pool.go b/remoting/getty/pool.go index 813aacba7f50a12ab0c0b95efd3b8ef64228e9a3..8ceb673aa9ef714d9189355a16de03628269b04c 100644 --- a/remoting/getty/pool.go +++ b/remoting/getty/pool.go @@ -81,19 +81,26 @@ func newGettyRPCClientConn(pool *gettyRPCClientPool, addr string) (*gettyRPCClie gettyClient: gettyClient, } go c.gettyClient.RunEventLoop(c.newSession) + idx := 1 - times := int(pool.rpcClient.opts.ConnectTimeout / 1e6) + start := time.Now() + connectTimeout := pool.rpcClient.opts.ConnectTimeout for { idx++ if c.isAvailable() { break } - if idx > times { + if time.Now().Sub(start) > connectTimeout { c.gettyClient.Close() - return nil, perrors.New(fmt.Sprintf("failed to create client connection to %s in %f seconds", addr, float32(times)/1000)) + return nil, perrors.New(fmt.Sprintf("failed to create client connection to %s in %s", addr, connectTimeout)) + } + + interval := time.Millisecond * time.Duration(idx) + if interval > time.Duration(100e6) { + interval = 100e6 // 100 ms } - time.Sleep(time.Millisecond * time.Duration(times)) + time.Sleep(interval) } logger.Debug("client init ok") c.updateActive(time.Now().Unix()) diff --git a/test/integrate/dubbo/go-client/go.sum b/test/integrate/dubbo/go-client/go.sum index 7bb51161b1a85755531e6c3ad5245e5918cb9680..fc378395782f0f7e8032cdaed2ec4c4b0266c149 100644 --- a/test/integrate/dubbo/go-client/go.sum +++ b/test/integrate/dubbo/go-client/go.sum @@ -1,4 +1,5 @@ github.com/apache/dubbo-go-hessian2 v1.6.0-rc1.0.20200906044240-6c1fb5c3bd44/go.mod h1:7rEw9guWABQa6Aqb8HeZcsYPHsOS7XT1qtJvkmI6c5w= +github.com/apache/dubbo-go-hessian2 v1.7.0/go.mod h1:7rEw9guWABQa6Aqb8HeZcsYPHsOS7XT1qtJvkmI6c5w= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dubbogo/gost v1.9.0/go.mod h1:pPTjVyoJan3aPxBPNUX0ADkXjPibLo+/Ib0/fADXSG8= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= diff --git a/test/integrate/dubbo/go-server/go.sum b/test/integrate/dubbo/go-server/go.sum index 7bb51161b1a85755531e6c3ad5245e5918cb9680..fc378395782f0f7e8032cdaed2ec4c4b0266c149 100644 --- a/test/integrate/dubbo/go-server/go.sum +++ b/test/integrate/dubbo/go-server/go.sum @@ -1,4 +1,5 @@ github.com/apache/dubbo-go-hessian2 v1.6.0-rc1.0.20200906044240-6c1fb5c3bd44/go.mod h1:7rEw9guWABQa6Aqb8HeZcsYPHsOS7XT1qtJvkmI6c5w= +github.com/apache/dubbo-go-hessian2 v1.7.0/go.mod h1:7rEw9guWABQa6Aqb8HeZcsYPHsOS7XT1qtJvkmI6c5w= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dubbogo/gost v1.9.0/go.mod h1:pPTjVyoJan3aPxBPNUX0ADkXjPibLo+/Ib0/fADXSG8= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=