diff --git a/README.md b/README.md index 9bade617c8b05ec52c2018cf231ae036a7ae91d3..3f8394536f944518f8d969289147272c32f169da 100644 --- a/README.md +++ b/README.md @@ -176,5 +176,5 @@ About dubbo-go benchmarking report, please refer to [dubbo benchmarking report]( If you are using [apache/dubbo-go](github.com/apache/dubbo-go) and think that it helps you or want do some contributions to it, please add your company to to [the user list](https://github.com/apache/dubbo-go/issues/2) to let us know your needs.  - +  diff --git a/README_CN.md b/README_CN.md index 180759f36663a587ee02232e229ae7c3ebbb06c1..582c5cf04cba08d4167c87b40fd0e86a3aa2ceb0 100644 --- a/README_CN.md +++ b/README_CN.md @@ -175,5 +175,5 @@ go test ./... -coverprofile=coverage.txt -covermode=atomic 鑻ヤ綘姝e湪浣跨敤 [apache/dubbo-go](github.com/apache/dubbo-go) 涓旇涓哄叾鏈夌敤鎴栬€呭悜瀵瑰叾鍋氭敼杩涳紝璇峰繚鍒楄吹鍙镐俊鎭簬 [鐢ㄦ埛鍒楄〃](https://github.com/apache/dubbo-go/issues/2)锛屼互渚挎垜浠煡鏅撲箣銆�  - +  diff --git a/before_ut.bat b/before_ut.bat index 5e1c877af229b2b30bffc8b802cc35b6aab6c80a..dc51008dadaad21af6fcb6021863ff4102b0afa2 100644 --- a/before_ut.bat +++ b/before_ut.bat @@ -20,7 +20,7 @@ set zkJarPath=remoting/zookeeper/zookeeper-4unittest/contrib/fatjar set zkJar=%zkJarPath%/%zkJarName% if not exist "%zkJar%" ( - md %zkJarPath% + md "%zkJarPath%" curl -L %remoteJarUrl% -o %zkJar% ) diff --git a/cluster/cluster_impl/available_cluster_invoker_test.go b/cluster/cluster_impl/available_cluster_invoker_test.go index 61d1c934522008e4d9bc46bbd57eb6fed6bf00f9..063100020ad36192a051d1e736af7264cd8df42d 100644 --- a/cluster/cluster_impl/available_cluster_invoker_test.go +++ b/cluster/cluster_impl/available_cluster_invoker_test.go @@ -19,6 +19,7 @@ package cluster_impl import ( "context" + "fmt" "strings" "testing" ) @@ -32,6 +33,7 @@ import ( "github.com/apache/dubbo-go/cluster/directory" "github.com/apache/dubbo-go/cluster/loadbalance" "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" "github.com/apache/dubbo-go/protocol/invocation" @@ -39,7 +41,8 @@ import ( ) var ( - availableUrl, _ = common.NewURL("dubbo://192.168.1.1:20000/com.ikurento.user.UserProvider") + availableUrl, _ = common.NewURL(fmt.Sprintf("dubbo://%s:%d/com.ikurento.user.UserProvider", + constant.LOCAL_HOST_VALUE, constant.DEFAULT_PORT)) ) func registerAvailable(invoker *mock.MockInvoker) protocol.Invoker { diff --git a/cluster/cluster_impl/base_cluster_invoker.go b/cluster/cluster_impl/base_cluster_invoker.go index cabd6c5f17cd3a3310054c0ff7b9a9877d581345..bbdfa715d7cdc461689e60a5a41171ad5c9770e1 100644 --- a/cluster/cluster_impl/base_cluster_invoker.go +++ b/cluster/cluster_impl/base_cluster_invoker.go @@ -88,6 +88,10 @@ func (invoker *baseClusterInvoker) checkWhetherDestroyed() error { func (invoker *baseClusterInvoker) doSelect(lb cluster.LoadBalance, invocation protocol.Invocation, invokers []protocol.Invoker, invoked []protocol.Invoker) protocol.Invoker { var selectedInvoker protocol.Invoker + if len(invokers) <= 0 { + return selectedInvoker + } + url := invokers[0].GetUrl() sticky := url.GetParamBool(constant.STICKY_KEY, false) //Get the service method sticky config if have @@ -97,19 +101,17 @@ func (invoker *baseClusterInvoker) doSelect(lb cluster.LoadBalance, invocation p invoker.stickyInvoker = nil } - if sticky && invoker.stickyInvoker != nil && (invoked == nil || !isInvoked(invoker.stickyInvoker, invoked)) { - if invoker.availablecheck && invoker.stickyInvoker.IsAvailable() { - return invoker.stickyInvoker - } + if sticky && invoker.availablecheck && + invoker.stickyInvoker != nil && invoker.stickyInvoker.IsAvailable() && + (invoked == nil || !isInvoked(invoker.stickyInvoker, invoked)) { + return invoker.stickyInvoker } selectedInvoker = invoker.doSelectInvoker(lb, invocation, invokers, invoked) - if sticky { invoker.stickyInvoker = selectedInvoker } return selectedInvoker - } func (invoker *baseClusterInvoker) doSelectInvoker(lb cluster.LoadBalance, invocation protocol.Invocation, invokers []protocol.Invoker, invoked []protocol.Invoker) protocol.Invoker { diff --git a/cluster/cluster_impl/base_cluster_invoker_test.go b/cluster/cluster_impl/base_cluster_invoker_test.go index d074697b85a3cf5b770de90da4847043d98c9df1..695ffcddbbce5a1c65f806b4561670d726588aaa 100644 --- a/cluster/cluster_impl/base_cluster_invoker_test.go +++ b/cluster/cluster_impl/base_cluster_invoker_test.go @@ -33,7 +33,7 @@ import ( "github.com/apache/dubbo-go/protocol/invocation" ) -func Test_StickyNormal(t *testing.T) { +func TestStickyNormal(t *testing.T) { invokers := []protocol.Invoker{} for i := 0; i < 10; i++ { url, _ := common.NewURL(fmt.Sprintf("dubbo://192.168.1.%v:20000/com.ikurento.user.UserProvider", i)) @@ -43,12 +43,15 @@ func Test_StickyNormal(t *testing.T) { base := &baseClusterInvoker{} base.availablecheck = true invoked := []protocol.Invoker{} - result := base.doSelect(loadbalance.NewRandomLoadBalance(), invocation.NewRPCInvocation("getUser", nil, nil), invokers, invoked) - result1 := base.doSelect(loadbalance.NewRandomLoadBalance(), invocation.NewRPCInvocation("getUser", nil, nil), invokers, invoked) + + tmpRandomBalance := loadbalance.NewRandomLoadBalance() + tmpInvocation := invocation.NewRPCInvocation("getUser", nil, nil) + result := base.doSelect(tmpRandomBalance, tmpInvocation, invokers, invoked) + result1 := base.doSelect(tmpRandomBalance, tmpInvocation, invokers, invoked) assert.Equal(t, result, result1) } -func Test_StickyNormalWhenError(t *testing.T) { +func TestStickyNormalWhenError(t *testing.T) { invokers := []protocol.Invoker{} for i := 0; i < 10; i++ { url, _ := common.NewURL(fmt.Sprintf("dubbo://192.168.1.%v:20000/com.ikurento.user.UserProvider", i)) diff --git a/cluster/cluster_impl/broadcast_cluster_invoker_test.go b/cluster/cluster_impl/broadcast_cluster_invoker_test.go index 9b5733e98b142759c3317f9cb3e3d3f08eea81e4..08d0002ee79b2f3fda5a50ce90747c0aaad91932 100644 --- a/cluster/cluster_impl/broadcast_cluster_invoker_test.go +++ b/cluster/cluster_impl/broadcast_cluster_invoker_test.go @@ -20,6 +20,7 @@ package cluster_impl import ( "context" "errors" + "fmt" "testing" ) @@ -32,6 +33,7 @@ import ( "github.com/apache/dubbo-go/cluster/directory" "github.com/apache/dubbo-go/cluster/loadbalance" "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" "github.com/apache/dubbo-go/protocol/invocation" @@ -39,10 +41,11 @@ import ( ) var ( - broadcastUrl, _ = common.NewURL("dubbo://192.168.1.1:20000/com.ikurento.user.UserProvider") + broadcastUrl, _ = common.NewURL( + fmt.Sprintf("dubbo://%s:%d/com.ikurento.user.UserProvider", constant.LOCAL_HOST_VALUE, constant.DEFAULT_PORT)) ) -func registerBroadcast(t *testing.T, mockInvokers ...*mock.MockInvoker) protocol.Invoker { +func registerBroadcast(mockInvokers ...*mock.MockInvoker) protocol.Invoker { extension.SetLoadbalance("random", loadbalance.NewRandomLoadBalance) invokers := []protocol.Invoker{} @@ -59,7 +62,7 @@ func registerBroadcast(t *testing.T, mockInvokers ...*mock.MockInvoker) protocol return clusterInvoker } -func Test_BroadcastInvokeSuccess(t *testing.T) { +func TestBroadcastInvokeSuccess(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() @@ -72,13 +75,13 @@ func Test_BroadcastInvokeSuccess(t *testing.T) { invoker.EXPECT().Invoke(gomock.Any()).Return(mockResult) } - clusterInvoker := registerBroadcast(t, invokers...) + clusterInvoker := registerBroadcast(invokers...) result := clusterInvoker.Invoke(context.Background(), &invocation.RPCInvocation{}) assert.Equal(t, mockResult, result) } -func Test_BroadcastInvokeFailed(t *testing.T) { +func TestBroadcastInvokeFailed(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() @@ -102,7 +105,7 @@ func Test_BroadcastInvokeFailed(t *testing.T) { invoker.EXPECT().Invoke(gomock.Any()).Return(mockResult) } - clusterInvoker := registerBroadcast(t, invokers...) + clusterInvoker := registerBroadcast(invokers...) result := clusterInvoker.Invoke(context.Background(), &invocation.RPCInvocation{}) assert.Equal(t, mockFailedResult.Err, result.Error()) diff --git a/cluster/cluster_impl/failback_cluster_test.go b/cluster/cluster_impl/failback_cluster_test.go index 69418bc3b876f7c9375a2164d78bac2fcbb05043..0edb81d4285fa68ceefd96100b541ba334f95bda 100644 --- a/cluster/cluster_impl/failback_cluster_test.go +++ b/cluster/cluster_impl/failback_cluster_test.go @@ -19,6 +19,7 @@ package cluster_impl import ( "context" + "fmt" "sync" "testing" "time" @@ -34,6 +35,7 @@ import ( "github.com/apache/dubbo-go/cluster/directory" "github.com/apache/dubbo-go/cluster/loadbalance" "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" "github.com/apache/dubbo-go/protocol/invocation" @@ -41,11 +43,12 @@ import ( ) var ( - failbackUrl, _ = common.NewURL("dubbo://192.168.1.1:20000/com.ikurento.user.UserProvider") + failbackUrl, _ = common.NewURL( + fmt.Sprintf("dubbo://%s:%d/com.ikurento.user.UserProvider", constant.LOCAL_HOST_VALUE, constant.DEFAULT_PORT)) ) // registerFailback register failbackCluster to cluster extension. -func registerFailback(t *testing.T, invoker *mock.MockInvoker) protocol.Invoker { +func registerFailback(invoker *mock.MockInvoker) protocol.Invoker { extension.SetLoadbalance("random", loadbalance.NewRandomLoadBalance) failbackCluster := NewFailbackCluster() @@ -60,12 +63,12 @@ func registerFailback(t *testing.T, invoker *mock.MockInvoker) protocol.Invoker } // success firstly, failback should return origin invoke result. -func Test_FailbackSuceess(t *testing.T) { +func TestFailbackSuceess(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() invoker := mock.NewMockInvoker(ctrl) - clusterInvoker := registerFailback(t, invoker).(*failbackClusterInvoker) + clusterInvoker := registerFailback(invoker).(*failbackClusterInvoker) invoker.EXPECT().GetUrl().Return(failbackUrl).AnyTimes() @@ -77,12 +80,12 @@ func Test_FailbackSuceess(t *testing.T) { } // failed firstly, success later after one retry. -func Test_FailbackRetryOneSuccess(t *testing.T) { +func TestFailbackRetryOneSuccess(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() invoker := mock.NewMockInvoker(ctrl) - clusterInvoker := registerFailback(t, invoker).(*failbackClusterInvoker) + clusterInvoker := registerFailback(invoker).(*failbackClusterInvoker) invoker.EXPECT().GetUrl().Return(failbackUrl).AnyTimes() @@ -95,7 +98,7 @@ func Test_FailbackRetryOneSuccess(t *testing.T) { wg.Add(1) now := time.Now() mockSuccResult := &protocol.RPCResult{Rest: rest{tried: 0, success: true}} - invoker.EXPECT().Invoke(gomock.Any()).DoAndReturn(func(invocation protocol.Invocation) protocol.Result { + invoker.EXPECT().Invoke(gomock.Any()).DoAndReturn(func(protocol.Invocation) protocol.Result { delta := time.Since(now).Nanoseconds() / int64(time.Second) assert.True(t, delta >= 5) wg.Done() @@ -120,12 +123,12 @@ func Test_FailbackRetryOneSuccess(t *testing.T) { } // failed firstly, and failed again after ech retry time. -func Test_FailbackRetryFailed(t *testing.T) { +func TestFailbackRetryFailed(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() invoker := mock.NewMockInvoker(ctrl) - clusterInvoker := registerFailback(t, invoker).(*failbackClusterInvoker) + clusterInvoker := registerFailback(invoker).(*failbackClusterInvoker) invoker.EXPECT().GetUrl().Return(failbackUrl).AnyTimes() @@ -141,7 +144,7 @@ func Test_FailbackRetryFailed(t *testing.T) { // add retry call that eventually failed. for i := 0; i < retries; i++ { j := i + 1 - invoker.EXPECT().Invoke(gomock.Any()).DoAndReturn(func(invocation protocol.Invocation) protocol.Result { + invoker.EXPECT().Invoke(gomock.Any()).DoAndReturn(func(protocol.Invocation) protocol.Result { delta := time.Since(now).Nanoseconds() / int64(time.Second) assert.True(t, delta >= int64(5*j)) wg.Done() @@ -166,12 +169,12 @@ func Test_FailbackRetryFailed(t *testing.T) { } // add 10 tasks but all failed firstly, and failed again with one retry. -func Test_FailbackRetryFailed10Times(t *testing.T) { +func TestFailbackRetryFailed10Times(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() invoker := mock.NewMockInvoker(ctrl) - clusterInvoker := registerFailback(t, invoker).(*failbackClusterInvoker) + clusterInvoker := registerFailback(invoker).(*failbackClusterInvoker) clusterInvoker.maxRetries = 10 invoker.EXPECT().GetUrl().Return(failbackUrl).AnyTimes() @@ -184,7 +187,7 @@ func Test_FailbackRetryFailed10Times(t *testing.T) { var wg sync.WaitGroup wg.Add(10) now := time.Now() - invoker.EXPECT().Invoke(gomock.Any()).DoAndReturn(func(invocation protocol.Invocation) protocol.Result { + invoker.EXPECT().Invoke(gomock.Any()).DoAndReturn(func(protocol.Invocation) protocol.Result { delta := time.Since(now).Nanoseconds() / int64(time.Second) assert.True(t, delta >= 5) wg.Done() @@ -208,12 +211,12 @@ func Test_FailbackRetryFailed10Times(t *testing.T) { assert.Equal(t, int64(0), clusterInvoker.taskList.Len()) } -func Test_FailbackOutOfLimit(t *testing.T) { +func TestFailbackOutOfLimit(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() invoker := mock.NewMockInvoker(ctrl) - clusterInvoker := registerFailback(t, invoker).(*failbackClusterInvoker) + clusterInvoker := registerFailback(invoker).(*failbackClusterInvoker) clusterInvoker.failbackTasks = 1 invoker.EXPECT().GetUrl().Return(failbackUrl).AnyTimes() diff --git a/cluster/cluster_impl/failfast_cluster_test.go b/cluster/cluster_impl/failfast_cluster_test.go index c5ab7cd5410ea312e082f8064c13b2356c9b4bb4..77e8e9c5da73bfc8bcf08dbd90351bfd23d7e651 100644 --- a/cluster/cluster_impl/failfast_cluster_test.go +++ b/cluster/cluster_impl/failfast_cluster_test.go @@ -19,6 +19,7 @@ package cluster_impl import ( "context" + "fmt" "testing" ) @@ -32,6 +33,7 @@ import ( "github.com/apache/dubbo-go/cluster/directory" "github.com/apache/dubbo-go/cluster/loadbalance" "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" "github.com/apache/dubbo-go/protocol/invocation" @@ -39,11 +41,12 @@ import ( ) var ( - failfastUrl, _ = common.NewURL("dubbo://192.168.1.1:20000/com.ikurento.user.UserProvider") + failfastUrl, _ = common.NewURL( + fmt.Sprintf("dubbo://%s:%d/com.ikurento.user.UserProvider", constant.LOCAL_HOST_VALUE, constant.DEFAULT_PORT)) ) // registerFailfast register failfastCluster to cluster extension. -func registerFailfast(t *testing.T, invoker *mock.MockInvoker) protocol.Invoker { +func registerFailfast(invoker *mock.MockInvoker) protocol.Invoker { extension.SetLoadbalance("random", loadbalance.NewRandomLoadBalance) failfastCluster := NewFailFastCluster() @@ -57,12 +60,12 @@ func registerFailfast(t *testing.T, invoker *mock.MockInvoker) protocol.Invoker return clusterInvoker } -func Test_FailfastInvokeSuccess(t *testing.T) { +func TestFailfastInvokeSuccess(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() invoker := mock.NewMockInvoker(ctrl) - clusterInvoker := registerFailfast(t, invoker) + clusterInvoker := registerFailfast(invoker) invoker.EXPECT().GetUrl().Return(failfastUrl).AnyTimes() @@ -77,12 +80,12 @@ func Test_FailfastInvokeSuccess(t *testing.T) { assert.Equal(t, 0, res.tried) } -func Test_FailfastInvokeFail(t *testing.T) { +func TestFailfastInvokeFail(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() invoker := mock.NewMockInvoker(ctrl) - clusterInvoker := registerFailfast(t, invoker) + clusterInvoker := registerFailfast(invoker) invoker.EXPECT().GetUrl().Return(failfastUrl).AnyTimes() diff --git a/cluster/cluster_impl/failover_cluster_invoker.go b/cluster/cluster_impl/failover_cluster_invoker.go index 6178a05a1226ba629d2456ad6886b02a26288e45..66adabd1043d6e5d770704774dda22ba9e6faebe 100644 --- a/cluster/cluster_impl/failover_cluster_invoker.go +++ b/cluster/cluster_impl/failover_cluster_invoker.go @@ -45,52 +45,35 @@ func newFailoverClusterInvoker(directory cluster.Directory) protocol.Invoker { } func (invoker *failoverClusterInvoker) Invoke(ctx context.Context, invocation protocol.Invocation) protocol.Result { + var ( + result protocol.Result + invoked []protocol.Invoker + providers []string + ) invokers := invoker.directory.List(invocation) - err := invoker.checkInvokers(invokers, invocation) - - if err != nil { + if err := invoker.checkInvokers(invokers, invocation); err != nil { return &protocol.RPCResult{Err: err} } - loadbalance := getLoadBalance(invokers[0], invocation) - methodName := invocation.MethodName() - url := invokers[0].GetUrl() - - //get reties - retriesConfig := url.GetParam(constant.RETRIES_KEY, constant.DEFAULT_RETRIES) + retries := getRetries(invokers, methodName) + loadBalance := getLoadBalance(invokers[0], invocation) - //Get the service method loadbalance config if have - if v := url.GetMethodParam(methodName, constant.RETRIES_KEY, ""); len(v) != 0 { - retriesConfig = v - } - retries, err := strconv.Atoi(retriesConfig) - if err != nil || retries < 0 { - logger.Error("Your retries config is invalid,pls do a check. And will use the default retries configuration instead.") - retries = constant.DEFAULT_RETRIES_INT - } - invoked := []protocol.Invoker{} - providers := []string{} - var result protocol.Result - if retries > len(invokers) { - retries = len(invokers) - } for i := 0; i <= retries; i++ { //Reselect before retry to avoid a change of candidate `invokers`. //NOTE: if `invokers` changed, then `invoked` also lose accuracy. if i > 0 { - err := invoker.checkWhetherDestroyed() - if err != nil { + if err := invoker.checkWhetherDestroyed(); err != nil { return &protocol.RPCResult{Err: err} } + invokers = invoker.directory.List(invocation) - err = invoker.checkInvokers(invokers, invocation) - if err != nil { + if err := invoker.checkInvokers(invokers, invocation); err != nil { return &protocol.RPCResult{Err: err} } } - ivk := invoker.doSelect(loadbalance, invocation, invokers, invoked) + ivk := invoker.doSelect(loadBalance, invocation, invokers, invoked) if ivk == nil { continue } @@ -100,13 +83,40 @@ func (invoker *failoverClusterInvoker) Invoke(ctx context.Context, invocation pr if result.Error() != nil { providers = append(providers, ivk.GetUrl().Key()) continue - } else { - return result } + return result } + ip, _ := gxnet.GetLocalIP() - return &protocol.RPCResult{Err: perrors.Errorf("Failed to invoke the method %v in the service %v. Tried %v times of "+ - "the providers %v (%v/%v)from the registry %v on the consumer %v using the dubbo version %v. Last error is %v.", - methodName, invoker.GetUrl().Service(), retries, providers, len(providers), len(invokers), invoker.directory.GetUrl(), ip, constant.Version, result.Error().Error(), - )} + invokerSvc := invoker.GetUrl().Service() + invokerUrl := invoker.directory.GetUrl() + return &protocol.RPCResult{ + Err: perrors.Errorf("Failed to invoke the method %v in the service %v. Tried %v times of the providers %v (%v/%v)from the registry %v on the consumer %v using the dubbo version %v. Last error is %v.", + methodName, invokerSvc, retries, providers, len(providers), len(invokers), invokerUrl, ip, constant.Version, result.Error().Error(), + )} +} + +func getRetries(invokers []protocol.Invoker, methodName string) int { + if len(invokers) <= 0 { + return constant.DEFAULT_RETRIES_INT + } + + url := invokers[0].GetUrl() + //get reties + retriesConfig := url.GetParam(constant.RETRIES_KEY, constant.DEFAULT_RETRIES) + //Get the service method loadbalance config if have + if v := url.GetMethodParam(methodName, constant.RETRIES_KEY, ""); len(v) != 0 { + retriesConfig = v + } + + retries, err := strconv.Atoi(retriesConfig) + if err != nil || retries < 0 { + logger.Error("Your retries config is invalid,pls do a check. And will use the default retries configuration instead.") + retries = constant.DEFAULT_RETRIES_INT + } + + if retries > len(invokers) { + retries = len(invokers) + } + return retries } diff --git a/cluster/cluster_impl/failover_cluster_test.go b/cluster/cluster_impl/failover_cluster_test.go index ee7d48f3497772db3143b1ae62a30f66f99faa58..e05b79202cd202334db1c19421e3163ee28bac26 100644 --- a/cluster/cluster_impl/failover_cluster_test.go +++ b/cluster/cluster_impl/failover_cluster_test.go @@ -101,7 +101,7 @@ func (bi *MockInvoker) Destroy() { var count int -func normalInvoke(t *testing.T, successCount int, urlParam url.Values, invocations ...*invocation.RPCInvocation) protocol.Result { +func normalInvoke(successCount int, urlParam url.Values, invocations ...*invocation.RPCInvocation) protocol.Result { extension.SetLoadbalance("random", loadbalance.NewRandomLoadBalance) failoverCluster := NewFailoverCluster() @@ -119,40 +119,40 @@ func normalInvoke(t *testing.T, successCount int, urlParam url.Values, invocatio return clusterInvoker.Invoke(context.Background(), &invocation.RPCInvocation{}) } -func Test_FailoverInvokeSuccess(t *testing.T) { +func TestFailoverInvokeSuccess(t *testing.T) { urlParams := url.Values{} - result := normalInvoke(t, 3, urlParams) + result := normalInvoke(3, urlParams) assert.NoError(t, result.Error()) count = 0 } -func Test_FailoverInvokeFail(t *testing.T) { +func TestFailoverInvokeFail(t *testing.T) { urlParams := url.Values{} - result := normalInvoke(t, 4, urlParams) + result := normalInvoke(4, urlParams) assert.Errorf(t, result.Error(), "error") count = 0 } -func Test_FailoverInvoke1(t *testing.T) { +func TestFailoverInvoke1(t *testing.T) { urlParams := url.Values{} urlParams.Set(constant.RETRIES_KEY, "3") - result := normalInvoke(t, 4, urlParams) + result := normalInvoke(4, urlParams) assert.NoError(t, result.Error()) count = 0 } -func Test_FailoverInvoke2(t *testing.T) { +func TestFailoverInvoke2(t *testing.T) { urlParams := url.Values{} urlParams.Set(constant.RETRIES_KEY, "2") urlParams.Set("methods.test."+constant.RETRIES_KEY, "3") ivc := invocation.NewRPCInvocationWithOptions(invocation.WithMethodName("test")) - result := normalInvoke(t, 4, urlParams, ivc) + result := normalInvoke(4, urlParams, ivc) assert.NoError(t, result.Error()) count = 0 } -func Test_FailoverDestroy(t *testing.T) { +func TestFailoverDestroy(t *testing.T) { extension.SetLoadbalance("random", loadbalance.NewRandomLoadBalance) failoverCluster := NewFailoverCluster() @@ -170,5 +170,4 @@ func Test_FailoverDestroy(t *testing.T) { count = 0 clusterInvoker.Destroy() assert.Equal(t, false, clusterInvoker.IsAvailable()) - } diff --git a/cluster/cluster_impl/failsafe_cluster_test.go b/cluster/cluster_impl/failsafe_cluster_test.go index 0bfeb576bd095508ef122c55c1345208c50eb339..d9a716e1ae65a84b605b4b7af1872b3a85dc9369 100644 --- a/cluster/cluster_impl/failsafe_cluster_test.go +++ b/cluster/cluster_impl/failsafe_cluster_test.go @@ -19,6 +19,7 @@ package cluster_impl import ( "context" + "fmt" "testing" ) @@ -32,6 +33,7 @@ import ( "github.com/apache/dubbo-go/cluster/directory" "github.com/apache/dubbo-go/cluster/loadbalance" "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" "github.com/apache/dubbo-go/protocol/invocation" @@ -39,11 +41,12 @@ import ( ) var ( - failsafeUrl, _ = common.NewURL("dubbo://192.168.1.1:20000/com.ikurento.user.UserProvider") + failsafeUrl, _ = common.NewURL( + fmt.Sprintf("dubbo://%s:%d/com.ikurento.user.UserProvider", constant.LOCAL_HOST_VALUE, constant.DEFAULT_PORT)) ) // registerFailsafe register failsafeCluster to cluster extension. -func registerFailsafe(t *testing.T, invoker *mock.MockInvoker) protocol.Invoker { +func registerFailsafe(invoker *mock.MockInvoker) protocol.Invoker { extension.SetLoadbalance("random", loadbalance.NewRandomLoadBalance) failsafeCluster := NewFailsafeCluster() @@ -57,12 +60,12 @@ func registerFailsafe(t *testing.T, invoker *mock.MockInvoker) protocol.Invoker return clusterInvoker } -func Test_FailSafeInvokeSuccess(t *testing.T) { +func TestFailSafeInvokeSuccess(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() invoker := mock.NewMockInvoker(ctrl) - clusterInvoker := registerFailsafe(t, invoker) + clusterInvoker := registerFailsafe(invoker) invoker.EXPECT().GetUrl().Return(failsafeUrl).AnyTimes() @@ -76,12 +79,12 @@ func Test_FailSafeInvokeSuccess(t *testing.T) { assert.True(t, res.success) } -func Test_FailSafeInvokeFail(t *testing.T) { +func TestFailSafeInvokeFail(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() invoker := mock.NewMockInvoker(ctrl) - clusterInvoker := registerFailsafe(t, invoker) + clusterInvoker := registerFailsafe(invoker) invoker.EXPECT().GetUrl().Return(failsafeUrl).AnyTimes() diff --git a/cluster/cluster_impl/forking_cluster_invoker.go b/cluster/cluster_impl/forking_cluster_invoker.go index 732569416daea8f878569db143271139b791ceca..a5a3f2ec6605dfb843fab09dff0a53000bbc3298 100644 --- a/cluster/cluster_impl/forking_cluster_invoker.go +++ b/cluster/cluster_impl/forking_cluster_invoker.go @@ -46,14 +46,12 @@ func newForkingClusterInvoker(directory cluster.Directory) protocol.Invoker { // Invoke ... func (invoker *forkingClusterInvoker) Invoke(ctx context.Context, invocation protocol.Invocation) protocol.Result { - err := invoker.checkWhetherDestroyed() - if err != nil { + if err := invoker.checkWhetherDestroyed(); err != nil { return &protocol.RPCResult{Err: err} } invokers := invoker.directory.List(invocation) - err = invoker.checkInvokers(invokers, invocation) - if err != nil { + if err := invoker.checkInvokers(invokers, invocation); err != nil { return &protocol.RPCResult{Err: err} } @@ -63,11 +61,9 @@ func (invoker *forkingClusterInvoker) Invoke(ctx context.Context, invocation pro if forks < 0 || forks > len(invokers) { selected = invokers } else { - selected = make([]protocol.Invoker, 0) - loadbalance := getLoadBalance(invokers[0], invocation) + loadBalance := getLoadBalance(invokers[0], invocation) for i := 0; i < forks; i++ { - ivk := invoker.doSelect(loadbalance, invocation, invokers, selected) - if ivk != nil { + if ivk := invoker.doSelect(loadBalance, invocation, invokers, selected); ivk != nil { selected = append(selected, ivk) } } @@ -77,8 +73,7 @@ func (invoker *forkingClusterInvoker) Invoke(ctx context.Context, invocation pro for _, ivk := range selected { go func(k protocol.Invoker) { result := k.Invoke(ctx, invocation) - err := resultQ.Put(result) - if err != nil { + if err := resultQ.Put(result); err != nil { logger.Errorf("resultQ put failed with exception: %v.\n", err) } }(ivk) @@ -99,6 +94,5 @@ func (invoker *forkingClusterInvoker) Invoke(ctx context.Context, invocation pro if !ok { return &protocol.RPCResult{Err: fmt.Errorf("failed to forking invoke provider %v, but not legal resp", selected)} } - return result } diff --git a/cluster/cluster_impl/forking_cluster_test.go b/cluster/cluster_impl/forking_cluster_test.go index 526b137d71c46c166367ac3b3308f9ad5b941538..a2fa136d312db900f45449c92a59009c6661571c 100644 --- a/cluster/cluster_impl/forking_cluster_test.go +++ b/cluster/cluster_impl/forking_cluster_test.go @@ -19,6 +19,7 @@ package cluster_impl import ( "context" + "fmt" "strconv" "sync" "testing" @@ -42,10 +43,11 @@ import ( ) var ( - forkingUrl, _ = common.NewURL("dubbo://192.168.1.1:20000/com.ikurento.user.UserProvider") + forkingUrl, _ = common.NewURL( + fmt.Sprintf("dubbo://%s:%d/com.ikurento.user.UserProvider", constant.LOCAL_HOST_VALUE, constant.DEFAULT_PORT)) ) -func registerForking(t *testing.T, mockInvokers ...*mock.MockInvoker) protocol.Invoker { +func registerForking(mockInvokers ...*mock.MockInvoker) protocol.Invoker { extension.SetLoadbalance(loadbalance.RoundRobin, loadbalance.NewRoundRobinLoadBalance) invokers := []protocol.Invoker{} @@ -62,7 +64,7 @@ func registerForking(t *testing.T, mockInvokers ...*mock.MockInvoker) protocol.I return clusterInvoker } -func Test_ForkingInvokeSuccess(t *testing.T) { +func TestForkingInvokeSuccess(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() @@ -79,20 +81,20 @@ func Test_ForkingInvokeSuccess(t *testing.T) { invokers = append(invokers, invoker) invoker.EXPECT().IsAvailable().Return(true).AnyTimes() invoker.EXPECT().Invoke(gomock.Any()).DoAndReturn( - func(invocation protocol.Invocation) protocol.Result { + func(protocol.Invocation) protocol.Result { wg.Done() return mockResult }) } - clusterInvoker := registerForking(t, invokers...) + clusterInvoker := registerForking(invokers...) result := clusterInvoker.Invoke(context.Background(), &invocation.RPCInvocation{}) assert.Equal(t, mockResult, result) wg.Wait() } -func Test_ForkingInvokeTimeout(t *testing.T) { +func TestForkingInvokeTimeout(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() @@ -108,14 +110,14 @@ func Test_ForkingInvokeTimeout(t *testing.T) { invokers = append(invokers, invoker) invoker.EXPECT().IsAvailable().Return(true).AnyTimes() invoker.EXPECT().Invoke(gomock.Any()).DoAndReturn( - func(invocation protocol.Invocation) protocol.Result { + func(protocol.Invocation) protocol.Result { time.Sleep(2 * time.Second) wg.Done() return mockResult }) } - clusterInvoker := registerForking(t, invokers...) + clusterInvoker := registerForking(invokers...) result := clusterInvoker.Invoke(context.Background(), &invocation.RPCInvocation{}) assert.NotNil(t, result) @@ -123,7 +125,7 @@ func Test_ForkingInvokeTimeout(t *testing.T) { wg.Wait() } -func Test_ForkingInvokeHalfTimeout(t *testing.T) { +func TestForkingInvokeHalfTimeout(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() @@ -140,13 +142,13 @@ func Test_ForkingInvokeHalfTimeout(t *testing.T) { invoker.EXPECT().IsAvailable().Return(true).AnyTimes() if i == 1 { invoker.EXPECT().Invoke(gomock.Any()).DoAndReturn( - func(invocation protocol.Invocation) protocol.Result { + func(protocol.Invocation) protocol.Result { wg.Done() return mockResult }) } else { invoker.EXPECT().Invoke(gomock.Any()).DoAndReturn( - func(invocation protocol.Invocation) protocol.Result { + func(protocol.Invocation) protocol.Result { time.Sleep(2 * time.Second) wg.Done() return mockResult @@ -154,7 +156,7 @@ func Test_ForkingInvokeHalfTimeout(t *testing.T) { } } - clusterInvoker := registerForking(t, invokers...) + clusterInvoker := registerForking(invokers...) result := clusterInvoker.Invoke(context.Background(), &invocation.RPCInvocation{}) assert.Equal(t, mockResult, result) diff --git a/cluster/cluster_impl/registry_aware_cluster_test.go b/cluster/cluster_impl/registry_aware_cluster_test.go index 3d0dcc0159839eb0a08aed842ee084449458c645..74584b44800fce3342956f4237a63ffbbabf5544 100644 --- a/cluster/cluster_impl/registry_aware_cluster_test.go +++ b/cluster/cluster_impl/registry_aware_cluster_test.go @@ -33,7 +33,7 @@ import ( "github.com/apache/dubbo-go/protocol/invocation" ) -func Test_RegAwareInvokeSuccess(t *testing.T) { +func TestRegAwareInvokeSuccess(t *testing.T) { regAwareCluster := NewRegistryAwareCluster() diff --git a/cluster/directory/base_directory_test.go b/cluster/directory/base_directory_test.go index 6dc55b39407c9e88d18a65b5ec02fa866571624b..8b60163b79b7120829e51f69238474a127133fb4 100644 --- a/cluster/directory/base_directory_test.go +++ b/cluster/directory/base_directory_test.go @@ -19,6 +19,7 @@ package directory import ( "encoding/base64" + "fmt" "testing" ) @@ -33,19 +34,20 @@ import ( "github.com/apache/dubbo-go/common/constant" ) +var ( + url, _ = common.NewURL( + fmt.Sprintf("dubbo://%s:%d/com.ikurento.user.UserProvider", constant.LOCAL_HOST_VALUE, constant.DEFAULT_PORT)) + anyUrl, _ = common.NewURL(fmt.Sprintf("condition://%s/com.foo.BarService", constant.ANYHOST_VALUE)) +) + func TestNewBaseDirectory(t *testing.T) { - url, _ := common.NewURL("dubbo://192.168.1.1:20000/com.ikurento.user.UserProvider") directory := NewBaseDirectory(&url) - assert.NotNil(t, directory) - assert.Equal(t, url, directory.GetUrl()) assert.Equal(t, &url, directory.GetDirectoryUrl()) - } func TestBuildRouterChain(t *testing.T) { - url, _ := common.NewURL("dubbo://192.168.1.1:20000/com.ikurento.user.UserProvider") directory := NewBaseDirectory(&url) assert.NotNil(t, directory) @@ -62,9 +64,8 @@ func TestBuildRouterChain(t *testing.T) { } func getRouteUrl(rule string) *common.URL { - url, _ := common.NewURL("condition://0.0.0.0/com.foo.BarService") - url.AddParam("rule", rule) - url.AddParam("force", "true") - url.AddParam(constant.ROUTER_KEY, "router") + anyUrl.AddParam("rule", rule) + anyUrl.AddParam("force", "true") + anyUrl.AddParam(constant.ROUTER_KEY, "router") return &url } diff --git a/cluster/directory/static_directory_test.go b/cluster/directory/static_directory_test.go index c50c9a4063bd1a372c27e47687cbf63850f76cef..8e75a2c2535058f605c3e9bb6d6a01f9ff91032a 100644 --- a/cluster/directory/static_directory_test.go +++ b/cluster/directory/static_directory_test.go @@ -32,7 +32,7 @@ import ( "github.com/apache/dubbo-go/protocol/invocation" ) -func Test_StaticDirList(t *testing.T) { +func TestStaticDirList(t *testing.T) { invokers := []protocol.Invoker{} for i := 0; i < 10; i++ { url, _ := common.NewURL(fmt.Sprintf("dubbo://192.168.1.%v:20000/com.ikurento.user.UserProvider", i)) @@ -45,7 +45,7 @@ func Test_StaticDirList(t *testing.T) { assert.Len(t, list, 10) } -func Test_StaticDirDestroy(t *testing.T) { +func TestStaticDirDestroy(t *testing.T) { invokers := []protocol.Invoker{} for i := 0; i < 10; i++ { url, _ := common.NewURL(fmt.Sprintf("dubbo://192.168.1.%v:20000/com.ikurento.user.UserProvider", i)) diff --git a/cluster/loadbalance/least_active_test.go b/cluster/loadbalance/least_active_test.go index 54e57e930f17008cf6d767ef47c0e754ac85d8f7..34be17a4f311a374eefc56ba76885eef2a23645a 100644 --- a/cluster/loadbalance/least_active_test.go +++ b/cluster/loadbalance/least_active_test.go @@ -28,6 +28,7 @@ import ( import ( "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" ) @@ -37,7 +38,7 @@ func TestLeastActiveSelect(t *testing.T) { var invokers []protocol.Invoker - url, _ := common.NewURL("dubbo://192.168.1.0:20000/org.apache.demo.HelloService") + url, _ := common.NewURL(fmt.Sprintf("dubbo://%s:%d/org.apache.demo.HelloService", constant.LOCAL_HOST_VALUE, constant.DEFAULT_PORT)) invokers = append(invokers, protocol.NewBaseInvoker(url)) i := loadBalance.Select(invokers, &invocation.RPCInvocation{}) assert.True(t, i.GetUrl().URLEqual(url)) diff --git a/cluster/loadbalance/random_test.go b/cluster/loadbalance/random_test.go index ff876f4aef8d229e8041594aaaa096f3ad5b1834..88392de52c93579dd4def3da2d60b415b601b21e 100644 --- a/cluster/loadbalance/random_test.go +++ b/cluster/loadbalance/random_test.go @@ -36,7 +36,7 @@ import ( "github.com/apache/dubbo-go/protocol/invocation" ) -func Test_RandomlbSelect(t *testing.T) { +func TestRandomlbSelect(t *testing.T) { randomlb := NewRandomLoadBalance() invokers := []protocol.Invoker{} @@ -53,7 +53,7 @@ func Test_RandomlbSelect(t *testing.T) { randomlb.Select(invokers, &invocation.RPCInvocation{}) } -func Test_RandomlbSelectWeight(t *testing.T) { +func TestRandomlbSelectWeight(t *testing.T) { randomlb := NewRandomLoadBalance() invokers := []protocol.Invoker{} @@ -84,7 +84,7 @@ func Test_RandomlbSelectWeight(t *testing.T) { }) } -func Test_RandomlbSelectWarmup(t *testing.T) { +func TestRandomlbSelectWarmup(t *testing.T) { randomlb := NewRandomLoadBalance() invokers := []protocol.Invoker{} diff --git a/cluster/loadbalance/round_robin_test.go b/cluster/loadbalance/round_robin_test.go index 1517f2a20b473af57cc23e61b988aa5a6a04de31..5354bae458605ff56ec8a9b35d36730ecdc0babb 100644 --- a/cluster/loadbalance/round_robin_test.go +++ b/cluster/loadbalance/round_robin_test.go @@ -29,6 +29,7 @@ import ( import ( "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" ) @@ -38,7 +39,8 @@ func TestRoundRobinSelect(t *testing.T) { var invokers []protocol.Invoker - url, _ := common.NewURL("dubbo://192.168.1.0:20000/org.apache.demo.HelloService") + url, _ := common.NewURL(fmt.Sprintf("dubbo://%s:%d/org.apache.demo.HelloService", + constant.LOCAL_HOST_VALUE, constant.DEFAULT_PORT)) invokers = append(invokers, protocol.NewBaseInvoker(url)) i := loadBalance.Select(invokers, &invocation.RPCInvocation{}) assert.True(t, i.GetUrl().URLEqual(url)) diff --git a/cluster/router/chain/chain_test.go b/cluster/router/chain/chain_test.go index 0cb47c4a185fe19b5f70ea4db2b80aab2f1aada5..c7a75f3d8608ecb7a95dcf33027e71b61d7f00f5 100644 --- a/cluster/router/chain/chain_test.go +++ b/cluster/router/chain/chain_test.go @@ -42,10 +42,16 @@ import ( "github.com/apache/dubbo-go/remoting/zookeeper" ) +const ( + path = "/dubbo/config/dubbo/test-condition.condition-router" + zkPrefix = "zookeeper://127.0.0.1:" + anyUrl = "condition://0.0.0.0/com.foo.BarService" +) + func TestNewRouterChain(t *testing.T) { ts, z, _, err := zookeeper.NewMockZookeeperClient("test", 15*time.Second) assert.NoError(t, err) - err = z.Create("/dubbo/config/dubbo/test-condition.condition-router") + err = z.Create(path) assert.NoError(t, err) testyml := `enabled: true @@ -55,12 +61,12 @@ conditions: - => host != 172.22.3.91 ` - _, err = z.Conn.Set("/dubbo/config/dubbo/test-condition.condition-router", []byte(testyml), 0) + _, err = z.Conn.Set(path, []byte(testyml), 0) assert.NoError(t, err) defer ts.Stop() defer z.Close() - zkUrl, _ := common.NewURL("zookeeper://127.0.0.1:" + strconv.Itoa(ts.Servers[0].Port)) + zkUrl, _ := common.NewURL(zkPrefix + strconv.Itoa(ts.Servers[0].Port)) configuration, err := extension.GetConfigCenterFactory("zookeeper").GetDynamicConfiguration(&zkUrl) config.GetEnvInstance().SetDynamicConfiguration(configuration) @@ -92,10 +98,10 @@ func TestNewRouterChainURLNil(t *testing.T) { assert.NotNil(t, chain) } -func TestRouterChain_AddRouters(t *testing.T) { +func TestRouterChainAddRouters(t *testing.T) { ts, z, _, err := zookeeper.NewMockZookeeperClient("test", 15*time.Second) assert.NoError(t, err) - err = z.Create("/dubbo/config/dubbo/test-condition.condition-router") + err = z.Create(path) assert.NoError(t, err) testyml := `enabled: true @@ -105,12 +111,12 @@ conditions: - => host != 172.22.3.91 ` - _, err = z.Conn.Set("/dubbo/config/dubbo/test-condition.condition-router", []byte(testyml), 0) + _, err = z.Conn.Set(path, []byte(testyml), 0) assert.NoError(t, err) defer ts.Stop() defer z.Close() - zkUrl, _ := common.NewURL("zookeeper://127.0.0.1:" + strconv.Itoa(ts.Servers[0].Port)) + zkUrl, _ := common.NewURL(zkPrefix + strconv.Itoa(ts.Servers[0].Port)) configuration, err := extension.GetConfigCenterFactory("zookeeper").GetDynamicConfiguration(&zkUrl) config.GetEnvInstance().SetDynamicConfiguration(configuration) @@ -131,12 +137,12 @@ conditions: assert.Equal(t, 3, len(chain.routers)) } -func TestRouterChain_Route(t *testing.T) { +func TestRouterChainRoute(t *testing.T) { ts, z, _, err := zookeeper.NewMockZookeeperClient("test", 15*time.Second) defer ts.Stop() defer z.Close() - zkUrl, _ := common.NewURL("zookeeper://127.0.0.1:" + strconv.Itoa(ts.Servers[0].Port)) + zkUrl, _ := common.NewURL(zkPrefix + strconv.Itoa(ts.Servers[0].Port)) configuration, err := extension.GetConfigCenterFactory("zookeeper").GetDynamicConfiguration(&zkUrl) config.GetEnvInstance().SetDynamicConfiguration(configuration) @@ -158,10 +164,10 @@ func TestRouterChain_Route(t *testing.T) { assert.Equal(t, 1, len(finalInvokers)) } -func TestRouterChain_Route_AppRouter(t *testing.T) { +func TestRouterChainRouteAppRouter(t *testing.T) { ts, z, _, err := zookeeper.NewMockZookeeperClient("test", 15*time.Second) assert.NoError(t, err) - err = z.Create("/dubbo/config/dubbo/test-condition.condition-router") + err = z.Create(path) assert.NoError(t, err) testyml := `enabled: true @@ -171,12 +177,12 @@ conditions: - => host = 1.1.1.1 => host != 1.2.3.4 ` - _, err = z.Conn.Set("/dubbo/config/dubbo/test-condition.condition-router", []byte(testyml), 0) + _, err = z.Conn.Set(path, []byte(testyml), 0) assert.NoError(t, err) defer ts.Stop() defer z.Close() - zkUrl, _ := common.NewURL("zookeeper://127.0.0.1:" + strconv.Itoa(ts.Servers[0].Port)) + zkUrl, _ := common.NewURL(zkPrefix + strconv.Itoa(ts.Servers[0].Port)) configuration, err := extension.GetConfigCenterFactory("zookeeper").GetDynamicConfiguration(&zkUrl) config.GetEnvInstance().SetDynamicConfiguration(configuration) @@ -200,7 +206,7 @@ func TestRouterChain_Route_NoRoute(t *testing.T) { defer ts.Stop() defer z.Close() - zkUrl, _ := common.NewURL("zookeeper://127.0.0.1:" + strconv.Itoa(ts.Servers[0].Port)) + zkUrl, _ := common.NewURL(zkPrefix + strconv.Itoa(ts.Servers[0].Port)) configuration, err := extension.GetConfigCenterFactory("zookeeper").GetDynamicConfiguration(&zkUrl) config.GetEnvInstance().SetDynamicConfiguration(configuration) @@ -223,7 +229,7 @@ func TestRouterChain_Route_NoRoute(t *testing.T) { } func getConditionNoRouteUrl(applicationKey string) *common.URL { - url, _ := common.NewURL("condition://0.0.0.0/com.foo.BarService") + url, _ := common.NewURL(anyUrl) url.AddParam("application", applicationKey) url.AddParam("force", "true") rule := base64.URLEncoding.EncodeToString([]byte("host = 1.1.1.1 => host != 1.2.3.4")) @@ -232,7 +238,7 @@ func getConditionNoRouteUrl(applicationKey string) *common.URL { } func getConditionRouteUrl(applicationKey string) *common.URL { - url, _ := common.NewURL("condition://0.0.0.0/com.foo.BarService") + url, _ := common.NewURL(anyUrl) url.AddParam("application", applicationKey) url.AddParam("force", "true") rule := base64.URLEncoding.EncodeToString([]byte("host = 1.1.1.1 => host = 1.2.3.4")) @@ -241,7 +247,7 @@ func getConditionRouteUrl(applicationKey string) *common.URL { } func getRouteUrl(applicationKey string) *common.URL { - url, _ := common.NewURL("condition://0.0.0.0/com.foo.BarService") + url, _ := common.NewURL(anyUrl) url.AddParam("application", applicationKey) url.AddParam("force", "true") return &url diff --git a/cluster/router/condition/app_router_test.go b/cluster/router/condition/app_router_test.go index e99307625baf34fa6b744f168ff4e6cb8e042502..f37a483e8468bc57d3ce1e73172ccf9a05bc29f0 100644 --- a/cluster/router/condition/app_router_test.go +++ b/cluster/router/condition/app_router_test.go @@ -37,6 +37,10 @@ import ( "github.com/apache/dubbo-go/remoting/zookeeper" ) +const ( + path = "/dubbo/config/dubbo/test-condition.condition-router" +) + func TestNewAppRouter(t *testing.T) { testYML := `enabled: true @@ -47,10 +51,10 @@ conditions: ` ts, z, _, err := zookeeper.NewMockZookeeperClient("test", 15*time.Second) assert.NoError(t, err) - err = z.Create("/dubbo/config/dubbo/test-condition.condition-router") + err = z.Create(path) assert.NoError(t, err) - _, err = z.Conn.Set("/dubbo/config/dubbo/test-condition.condition-router", []byte(testYML), 0) + _, err = z.Conn.Set(path, []byte(testYML), 0) assert.NoError(t, err) defer ts.Stop() defer z.Close() @@ -93,10 +97,10 @@ conditions: ` ts, z, _, err := zookeeper.NewMockZookeeperClient("test", 15*time.Second) assert.NoError(t, err) - err = z.Create("/dubbo/config/dubbo/test-condition.condition-router") + err = z.Create(path) assert.NoError(t, err) - _, err = z.Conn.Set("/dubbo/config/dubbo/test-condition.condition-router", []byte(testYML), 0) + _, err = z.Conn.Set(path, []byte(testYML), 0) assert.NoError(t, err) defer ts.Stop() defer z.Close() @@ -130,10 +134,10 @@ conditions: ` ts, z, _, err := zookeeper.NewMockZookeeperClient("test", 15*time.Second) assert.NoError(t, err) - err = z.Create("/dubbo/config/dubbo/test-condition.condition-router") + err = z.Create(path) assert.NoError(t, err) - _, err = z.Conn.Set("/dubbo/config/dubbo/test-condition.condition-router", []byte(testYML), 0) + _, err = z.Conn.Set(path, []byte(testYML), 0) assert.NoError(t, err) defer ts.Stop() defer z.Close() diff --git a/cluster/router/condition/factory_test.go b/cluster/router/condition/factory_test.go index 99cec34096a55d3c2a967b63afdf5f6d0a77279a..a826cafb85ee1a30ac568db34e10dd2c9c9e87d0 100644 --- a/cluster/router/condition/factory_test.go +++ b/cluster/router/condition/factory_test.go @@ -38,6 +38,8 @@ import ( "github.com/apache/dubbo-go/protocol/invocation" ) +const anyUrl = "condition://0.0.0.0/com.foo.BarService" + type MockInvoker struct { url common.URL available bool @@ -59,21 +61,21 @@ func (bi *MockInvoker) GetUrl() common.URL { } func getRouteUrl(rule string) *common.URL { - url, _ := common.NewURL("condition://0.0.0.0/com.foo.BarService") + url, _ := common.NewURL(anyUrl) url.AddParam("rule", rule) url.AddParam("force", "true") return &url } func getRouteUrlWithForce(rule, force string) *common.URL { - url, _ := common.NewURL("condition://0.0.0.0/com.foo.BarService") + url, _ := common.NewURL(anyUrl) url.AddParam("rule", rule) url.AddParam("force", force) return &url } func getRouteUrlWithNoForce(rule string) *common.URL { - url, _ := common.NewURL("condition://0.0.0.0/com.foo.BarService") + url, _ := common.NewURL(anyUrl) url.AddParam("rule", rule) return &url } @@ -116,7 +118,7 @@ func (bi *MockInvoker) Destroy() { bi.available = false } -func TestRoute_matchWhen(t *testing.T) { +func TestRouteMatchWhen(t *testing.T) { inv := &invocation.RPCInvocation{} rule := base64.URLEncoding.EncodeToString([]byte("=> host = 1.2.3.4")) router, _ := newConditionRouterFactory().NewRouter(getRouteUrl(rule)) @@ -149,7 +151,7 @@ func TestRoute_matchWhen(t *testing.T) { assert.Equal(t, true, matchWhen6) } -func TestRoute_matchFilter(t *testing.T) { +func TestRouteMatchFilter(t *testing.T) { localIP, _ := gxnet.GetLocalIP() t.Logf("The local ip is %s", localIP) url1, _ := common.NewURL("dubbo://10.20.3.3:20880/com.foo.BarService?default.serialization=fastjson") @@ -184,7 +186,7 @@ func TestRoute_matchFilter(t *testing.T) { } -func TestRoute_methodRoute(t *testing.T) { +func TestRouteMethodRoute(t *testing.T) { 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")) router, _ := newConditionRouterFactory().NewRouter(getRouteUrl(rule)) @@ -207,7 +209,7 @@ func TestRoute_methodRoute(t *testing.T) { } -func TestRoute_ReturnFalse(t *testing.T) { +func TestRouteReturnFalse(t *testing.T) { url, _ := common.NewURL("") localIP, _ := gxnet.GetLocalIP() invokers := []protocol.Invoker{NewMockInvoker(url, 1), NewMockInvoker(url, 2), NewMockInvoker(url, 3)} @@ -219,7 +221,7 @@ func TestRoute_ReturnFalse(t *testing.T) { assert.Equal(t, 0, len(fileredInvokers)) } -func TestRoute_ReturnEmpty(t *testing.T) { +func TestRouteReturnEmpty(t *testing.T) { localIP, _ := gxnet.GetLocalIP() url, _ := common.NewURL("") invokers := []protocol.Invoker{NewMockInvoker(url, 1), NewMockInvoker(url, 2), NewMockInvoker(url, 3)} @@ -231,7 +233,7 @@ func TestRoute_ReturnEmpty(t *testing.T) { assert.Equal(t, 0, len(fileredInvokers)) } -func TestRoute_ReturnAll(t *testing.T) { +func TestRouteReturnAll(t *testing.T) { localIP, _ := gxnet.GetLocalIP() urlString := "dubbo://" + localIP + "/com.foo.BarService" dubboURL, _ := common.NewURL(urlString) @@ -247,7 +249,7 @@ func TestRoute_ReturnAll(t *testing.T) { assert.Equal(t, invokers, fileredInvokers) } -func TestRoute_HostFilter(t *testing.T) { +func TestRouteHostFilter(t *testing.T) { localIP, _ := gxnet.GetLocalIP() url1, _ := common.NewURL("dubbo://10.20.3.3:20880/com.foo.BarService") url2, _ := common.NewURL(fmt.Sprintf("dubbo://%s:20880/com.foo.BarService", localIP)) @@ -266,7 +268,7 @@ func TestRoute_HostFilter(t *testing.T) { assert.Equal(t, invoker3, fileredInvokers[1]) } -func TestRoute_Empty_HostFilter(t *testing.T) { +func TestRouteEmptyHostFilter(t *testing.T) { localIP, _ := gxnet.GetLocalIP() url1, _ := common.NewURL("dubbo://10.20.3.3:20880/com.foo.BarService") url2, _ := common.NewURL(fmt.Sprintf("dubbo://%s:20880/com.foo.BarService", localIP)) @@ -285,7 +287,7 @@ func TestRoute_Empty_HostFilter(t *testing.T) { assert.Equal(t, invoker3, fileredInvokers[1]) } -func TestRoute_False_HostFilter(t *testing.T) { +func TestRouteFalseHostFilter(t *testing.T) { localIP, _ := gxnet.GetLocalIP() url1, _ := common.NewURL("dubbo://10.20.3.3:20880/com.foo.BarService") url2, _ := common.NewURL(fmt.Sprintf("dubbo://%s:20880/com.foo.BarService", localIP)) @@ -304,7 +306,7 @@ func TestRoute_False_HostFilter(t *testing.T) { assert.Equal(t, invoker3, fileredInvokers[1]) } -func TestRoute_Placeholder(t *testing.T) { +func TestRoutePlaceholder(t *testing.T) { localIP, _ := gxnet.GetLocalIP() url1, _ := common.NewURL("dubbo://10.20.3.3:20880/com.foo.BarService") url2, _ := common.NewURL(fmt.Sprintf("dubbo://%s:20880/com.foo.BarService", localIP)) @@ -323,7 +325,7 @@ func TestRoute_Placeholder(t *testing.T) { assert.Equal(t, invoker3, fileredInvokers[1]) } -func TestRoute_NoForce(t *testing.T) { +func TestRouteNoForce(t *testing.T) { localIP, _ := gxnet.GetLocalIP() url1, _ := common.NewURL("dubbo://10.20.3.3:20880/com.foo.BarService") url2, _ := common.NewURL(fmt.Sprintf("dubbo://%s:20880/com.foo.BarService", localIP)) @@ -340,7 +342,7 @@ func TestRoute_NoForce(t *testing.T) { assert.Equal(t, invokers, fileredInvokers) } -func TestRoute_Force(t *testing.T) { +func TestRouteForce(t *testing.T) { localIP, _ := gxnet.GetLocalIP() url1, _ := common.NewURL("dubbo://10.20.3.3:20880/com.foo.BarService") url2, _ := common.NewURL(fmt.Sprintf("dubbo://%s:20880/com.foo.BarService", localIP)) diff --git a/cluster/router/healthcheck/default_health_check_test.go b/cluster/router/healthcheck/default_health_check_test.go index 74aa3940743a012f907cfe3d8811a618f07ff800..8a95d9a7e8dffdc3f30f94c76274a729837fc133 100644 --- a/cluster/router/healthcheck/default_health_check_test.go +++ b/cluster/router/healthcheck/default_health_check_test.go @@ -37,7 +37,7 @@ func TestDefaultHealthChecker_IsHealthy(t *testing.T) { defer protocol.CleanAllStatus() url, _ := common.NewURL("dubbo://192.168.10.10:20000/com.ikurento.user.UserProvider") hc := NewDefaultHealthChecker(&url).(*DefaultHealthChecker) - invoker := NewMockInvoker(url, 1) + invoker := NewMockInvoker(url) healthy := hc.IsHealthy(invoker) assert.True(t, healthy) diff --git a/cluster/router/healthcheck/factory_test.go b/cluster/router/healthcheck/factory_test.go index a9d94da7c37f0e0c9640de1386998a85823e80a6..c3a26a93896e185f0dea3732ca5afcf7687ad5ea 100644 --- a/cluster/router/healthcheck/factory_test.go +++ b/cluster/router/healthcheck/factory_test.go @@ -35,7 +35,7 @@ type MockInvoker struct { url common.URL } -func NewMockInvoker(url common.URL, successCount int) *MockInvoker { +func NewMockInvoker(url common.URL) *MockInvoker { return &MockInvoker{ url: url, } diff --git a/cluster/router/healthcheck/health_check_route_test.go b/cluster/router/healthcheck/health_check_route_test.go index 759ef93dbeb8d91a82eefd59060afbe8a10a4440..7bfffea705bfedade9d1d13ac7e9c380651335dd 100644 --- a/cluster/router/healthcheck/health_check_route_test.go +++ b/cluster/router/healthcheck/health_check_route_test.go @@ -44,9 +44,9 @@ func TestHealthCheckRouter_Route(t *testing.T) { hcr, _ := NewHealthCheckRouter(&consumerURL) var invokers []protocol.Invoker - invoker1 := NewMockInvoker(url1, 1) - invoker2 := NewMockInvoker(url2, 1) - invoker3 := NewMockInvoker(url3, 1) + invoker1 := NewMockInvoker(url1) + invoker2 := NewMockInvoker(url2) + invoker3 := NewMockInvoker(url3) invokers = append(invokers, invoker1, invoker2, invoker3) inv := invocation.NewRPCInvocation("test", nil, nil) res := hcr.Route(invokers, &consumerURL, inv) diff --git a/common/constant/default.go b/common/constant/default.go index 3c889158e460031f06b9401008c80f55200a46e4..c69989b4fbc3e95cb42c7f5e403989b9cff9215b 100644 --- a/common/constant/default.go +++ b/common/constant/default.go @@ -43,6 +43,7 @@ const ( DEFAULT_FAILBACK_TASKS = 100 DEFAULT_REST_CLIENT = "resty" DEFAULT_REST_SERVER = "go-restful" + DEFAULT_PORT = 20000 ) const ( @@ -58,6 +59,7 @@ const ( const ( ANY_VALUE = "*" ANYHOST_VALUE = "0.0.0.0" + LOCAL_HOST_VALUE = "192.168.1.1" REMOVE_VALUE_PREFIX = "-" ) diff --git a/common/constant/key.go b/common/constant/key.go index 9af387193e2ad47f5f6adb6f7c88eec6244467b2..5be63fe82ce61d41b0845e2e076e48c3aebcd0cb 100644 --- a/common/constant/key.go +++ b/common/constant/key.go @@ -119,6 +119,7 @@ const ( CONFIG_CLUSTER_KEY = "config.cluster" CONFIG_CHECK_KEY = "config.check" CONFIG_TIMEOUT_KET = "config.timeout" + CONFIG_LOG_DIR_KEY = "config.logDir" CONFIG_VERSION_KEY = "configVersion" COMPATIBLE_CONFIG_KEY = "compatible_config" ) diff --git a/common/extension/auth.go b/common/extension/auth.go index 7caae00e84fd80666ff79b599e12f8516e23209c..4fca0a8e8c255456720df9e4fd9852295715b160 100644 --- a/common/extension/auth.go +++ b/common/extension/auth.go @@ -32,7 +32,7 @@ func SetAuthenticator(name string, fcn func() filter.Authenticator) { } // GetAuthenticator finds the Authenticator with @name -// if not found, it will panic +// Panic if not found func GetAuthenticator(name string) filter.Authenticator { if authenticators[name] == nil { panic("authenticator for " + name + " is not existing, make sure you have import the package.") @@ -46,7 +46,7 @@ func SetAccesskeyStorages(name string, fcn func() filter.AccessKeyStorage) { } // GetAccesskeyStorages finds the storage with the @name. -// If not found, it will panic. +// Panic if not found func GetAccesskeyStorages(name string) filter.AccessKeyStorage { if accesskeyStorages[name] == nil { panic("accesskeyStorages for " + name + " is not existing, make sure you have import the package.") diff --git a/common/extension/config_center.go b/common/extension/config_center.go index 3cbced8d3bbcdb3dc7f9af800fa36681d6dc063d..5a2c52f32d070f5ec03bdae0b3cd47f869c28171 100644 --- a/common/extension/config_center.go +++ b/common/extension/config_center.go @@ -27,7 +27,7 @@ var ( ) // SetConfigCenter sets the DynamicConfiguration with @name -func SetConfigCenter(name string, v func(config *common.URL) (config_center.DynamicConfiguration, error)) { +func SetConfigCenter(name string, v func(*common.URL) (config_center.DynamicConfiguration, error)) { configCenters[name] = v } diff --git a/common/url_test.go b/common/url_test.go index 2372de520e88b0949023e88cec64871736dd6aa0..4d9dff9f373f5d2250deb577621cead8c991cf4d 100644 --- a/common/url_test.go +++ b/common/url_test.go @@ -118,6 +118,33 @@ func TestURL_URLEqual(t *testing.T) { u3, err := NewURL("dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider?interface=com.ikurento.user.UserProvider&group=gg&version=2.6.0") assert.NoError(t, err) assert.False(t, u1.URLEqual(u3)) + + // urlGroupAnyValue's group is * + urlGroupAnyValue, err := NewURL("dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider?interface=com.ikurento.user.UserProvider&group=*&version=2.6.0") + assert.NoError(t, err) + assert.True(t, u3.URLEqual(urlGroupAnyValue)) + + // test for enabled + urlEnabledEmpty, err := NewURL("dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider?interface=com.ikurento.user.UserProvider&group=*&version=2.6.0&enabled=") + assert.NoError(t, err) + assert.True(t, u3.URLEqual(urlEnabledEmpty)) + + urlEnabledFalse, err := NewURL("dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider?interface=com.ikurento.user.UserProvider&group=*&version=2.6.0&enabled=1") + assert.NoError(t, err) + assert.False(t, u3.URLEqual(urlEnabledFalse)) + + urlEnabledTrue, err := NewURL("dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider?interface=com.ikurento.user.UserProvider&group=*&version=2.6.0&enabled=true") + assert.NoError(t, err) + assert.True(t, u3.URLEqual(urlEnabledTrue)) + + urlEnabledAny, err := NewURL("dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider?interface=com.ikurento.user.UserProvider&group=*&version=2.6.0&enabled=*") + assert.NoError(t, err) + assert.True(t, u3.URLEqual(urlEnabledAny)) + + // test for category + categoryAny, err := NewURL("dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider?interface=com.ikurento.user.UserProvider&group=*&version=2.6.0&enabled=*&category=*") + assert.NoError(t, err) + assert.True(t, categoryAny.URLEqual(u3)) } func TestURL_GetParam(t *testing.T) { diff --git a/config/config_center_config.go b/config/config_center_config.go index 56d575e204d77d57204f839ca59fd1559fb1e33d..c9133dc26df0b05e3bb61df0f612d0e2914e98bb 100644 --- a/config/config_center_config.go +++ b/config/config_center_config.go @@ -46,6 +46,7 @@ type ConfigCenterConfig struct { Group string `default:"dubbo" yaml:"group" json:"group,omitempty"` Username string `yaml:"username" json:"username,omitempty"` Password string `yaml:"password" json:"password,omitempty"` + LogDir string `yaml:"log_dir" json:"log_dir,omitempty"` ConfigFile string `default:"dubbo.properties" yaml:"config_file" json:"config_file,omitempty"` Namespace string `default:"dubbo" yaml:"namespace" json:"namespace,omitempty"` AppConfigFile string `default:"dubbo.properties" yaml:"app_config_file" json:"app_config_file,omitempty"` @@ -73,5 +74,6 @@ func (c *ConfigCenterConfig) GetUrlMap() url.Values { urlMap.Set(constant.CONFIG_GROUP_KEY, c.Group) urlMap.Set(constant.CONFIG_CLUSTER_KEY, c.Cluster) urlMap.Set(constant.CONFIG_APP_ID_KEY, c.AppId) + urlMap.Set(constant.CONFIG_LOG_DIR_KEY, c.LogDir) return urlMap } diff --git a/config_center/dynamic_configuration_test.go b/config_center/dynamic_configuration_test.go new file mode 100644 index 0000000000000000000000000000000000000000..8b5a8d7cc5afea8559d563f82f5b2dd80c51488e --- /dev/null +++ b/config_center/dynamic_configuration_test.go @@ -0,0 +1,44 @@ +/* + * 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 config_center + +import ( + "testing" + "time" +) + +import ( + "github.com/stretchr/testify/assert" +) + +import ( + "github.com/apache/dubbo-go/common" +) + +func TestWithTimeout(t *testing.T) { + fa := WithTimeout(12 * time.Second) + opt := &Options{} + fa(opt) + assert.Equal(t, 12*time.Second, opt.Timeout) +} + +func TestGetRuleKey(t *testing.T) { + url, err := common.NewURL("dubbo://192.168.1.1:20000/com.ikurento.user.UserProvider?interface=test&group=groupA&version=0") + assert.NoError(t, err) + assert.Equal(t, "test:0:groupA", GetRuleKey(url)) +} diff --git a/config_center/nacos/client.go b/config_center/nacos/client.go index d3373e249bf99873dd3aa05b7488b0e7f38730ec..3b432819f43327888ade3da5303e445d6a2ef0fe 100644 --- a/config_center/nacos/client.go +++ b/config_center/nacos/client.go @@ -18,6 +18,7 @@ package nacos import ( + "path/filepath" "strconv" "strings" "sync" @@ -36,7 +37,8 @@ import ( "github.com/apache/dubbo-go/common/logger" ) -const logDir = "logs/nacos/log" +// Nacos Log dir, it can be override when creating client by config_center.log_dir +var logDir = filepath.Join("logs", "nacos", "log") // NacosClient Nacos client type NacosClient struct { @@ -87,6 +89,7 @@ func ValidateNacosClient(container nacosClientFacade, opts ...option) error { } url := container.GetUrl() + logDir = url.GetParam(constant.CONFIG_LOG_DIR_KEY, logDir) if container.NacosClient() == nil { //in dubbo ,every registry only connect one node ,so this is []string{r.Address} diff --git a/config_center/nacos/client_test.go b/config_center/nacos/client_test.go index ef63eeff6ddf4e5cd6fa2ba7da7996b3dbed94ac..53ab325c955517a859dab0df358a0387179351d3 100644 --- a/config_center/nacos/client_test.go +++ b/config_center/nacos/client_test.go @@ -53,3 +53,62 @@ func Test_newNacosClient(t *testing.T) { <-c.client.Done() c.Destroy() } + +func Test_setNacosClient(t *testing.T) { + server := mockCommonNacosServer() + nacosURL := server.Listener.Addr().String() + registryUrl, _ := common.NewURL(nacosURL) + c := &nacosDynamicConfiguration{ + url: ®istryUrl, + done: make(chan struct{}), + } + var client *NacosClient + client = &NacosClient{ + name: nacosClientName, + NacosAddrs: []string{nacosURL}, + Timeout: 15, + exit: make(chan struct{}), + onceClose: func() { + close(client.exit) + }, + } + c.SetNacosClient(client) + err := ValidateNacosClient(c, WithNacosName(nacosClientName)) + assert.NoError(t, err) + c.wg.Add(1) + go HandleClientRestart(c) + go func() { + // c.client.Close() and <-c.client.Done() have order requirements. + // If c.client.Close() is called first.It is possible that "go HandleClientRestart(c)" + // sets c.client to nil before calling c.client.Done(). + time.Sleep(time.Second) + c.client.Close() + }() + <-c.client.Done() + c.Destroy() +} + +func Test_newNacosClient_connectError(t *testing.T) { + nacosURL := "registry://127.0.0.1:8888" + registryUrl, err := common.NewURL(nacosURL) + assert.NoError(t, err) + c := &nacosDynamicConfiguration{ + url: ®istryUrl, + done: make(chan struct{}), + } + err = ValidateNacosClient(c, WithNacosName(nacosClientName)) + assert.NoError(t, err) + c.wg.Add(1) + go HandleClientRestart(c) + go func() { + // c.client.Close() and <-c.client.Done() have order requirements. + // If c.client.Close() is called first.It is possible that "go HandleClientRestart(c)" + // sets c.client to nil before calling c.client.Done(). + time.Sleep(time.Second) + c.client.Close() + }() + <-c.client.Done() + // let client do retry + time.Sleep(5 * time.Second) + c.Destroy() +} diff --git a/config_center/nacos/impl_test.go b/config_center/nacos/impl_test.go index 4032c91cda512b649140db6eea3dc11eeb482f27..ebaad1c19ddda1e00bd0f22ebd8c7c3cb57615a6 100644 --- a/config_center/nacos/impl_test.go +++ b/config_center/nacos/impl_test.go @@ -72,12 +72,13 @@ func initNacosData(t *testing.T) (*nacosDynamicConfiguration, error) { server := mockCommonNacosServer() nacosURL := strings.ReplaceAll(server.URL, "http", "registry") regurl, _ := common.NewURL(nacosURL) - nacosConfiguration, err := newNacosDynamicConfiguration(®url) + factory := &nacosDynamicConfigurationFactory{} + nacosConfiguration, err := factory.GetDynamicConfiguration(®url) assert.NoError(t, err) nacosConfiguration.SetParser(&parser.DefaultConfigurationParser{}) - return nacosConfiguration, err + return nacosConfiguration.(*nacosDynamicConfiguration), err } func Test_GetConfig(t *testing.T) { diff --git a/config_center/parser/configuration_parser_test.go b/config_center/parser/configuration_parser_test.go index 7a59ea9b48b8b8d2a84735a416bcba1bb9ec8652..3ba10f73a4549181f37b89aedd4aedf4612bd7d4 100644 --- a/config_center/parser/configuration_parser_test.go +++ b/config_center/parser/configuration_parser_test.go @@ -32,3 +32,58 @@ func TestDefaultConfigurationParser_Parser(t *testing.T) { assert.Equal(t, 2, len(m)) assert.Equal(t, "172.0.0.1", m["dubbo.registry.address"]) } + +func TestDefaultConfigurationParser_appItemToUrls_ParserToUrls(t *testing.T) { + parser := &DefaultConfigurationParser{} + content := `configVersion: 2.7.1 +scope: application +key: org.apache.dubbo-go.mockService +enabled: true +configs: +- type: application + enabled: true + addresses: + - 0.0.0.0 + providerAddresses: [] + services: + - org.apache.dubbo-go.mockService + applications: [] + parameters: + cluster: mock1 + side: provider` + urls, err := parser.ParseToUrls(content) + assert.NoError(t, err) + assert.Equal(t, 1, len(urls)) + assert.Equal(t, "org.apache.dubbo-go.mockService", urls[0].GetParam("application", "")) + assert.Equal(t, "mock1", urls[0].GetParam("cluster", "")) + assert.Equal(t, "override", urls[0].Protocol) + assert.Equal(t, "0.0.0.0", urls[0].Location) +} + +func TestDefaultConfigurationParser_serviceItemToUrls_ParserToUrls(t *testing.T) { + parser := &DefaultConfigurationParser{} + content := `configVersion: 2.7.1 +scope: notApplication +key: groupA/test:1 +enabled: true +configs: +- type: application + enabled: true + addresses: + - 0.0.0.0 + providerAddresses: [] + services: + - org.apache.dubbo-go.mockService + applications: [] + parameters: + cluster: mock1 + side: provider` + urls, err := parser.ParseToUrls(content) + assert.NoError(t, err) + assert.Equal(t, 1, len(urls)) + assert.Equal(t, "groupA", urls[0].GetParam("group", "")) + assert.Equal(t, "/test", urls[0].Path) + assert.Equal(t, "mock1", urls[0].GetParam("cluster", "")) + assert.Equal(t, "override", urls[0].Protocol) + assert.Equal(t, "0.0.0.0", urls[0].Location) +} diff --git a/filter/access_key.go b/filter/access_key.go index 40d4157b31d13ed8fd8b1ba8cc9d16b53638ac6a..4801d64fe46461424c5dac5aef2eebc719ee19c4 100644 --- a/filter/access_key.go +++ b/filter/access_key.go @@ -22,6 +22,7 @@ import ( "github.com/apache/dubbo-go/protocol" ) +// AccessKeyPair stores the basic attributes for authentication. type AccessKeyPair struct { AccessKey string `yaml:"accessKey" json:"accessKey,omitempty" property:"accessKey"` SecretKey string `yaml:"secretKey" json:"secretKey,omitempty" property:"secretKey"` @@ -31,8 +32,7 @@ type AccessKeyPair struct { Options string `yaml:"options" json:"options,omitempty" property:"options"` } -// AccessKeyStorage -// This SPI Extension support us to store our AccessKeyPair or load AccessKeyPair from other +// AccessKeyStorage supports us to store our AccessKeyPair or load AccessKeyPair from other // storage, such as filesystem. type AccessKeyStorage interface { GetAccessKeyPair(protocol.Invocation, *common.URL) *AccessKeyPair diff --git a/filter/authenticator.go b/filter/authenticator.go index ac2c8601d4a0d2e5ae3aed56415d9d23856cb502..71f659d4918293e2eb05b8b7a72b6db1cece42ba 100644 --- a/filter/authenticator.go +++ b/filter/authenticator.go @@ -22,14 +22,13 @@ import ( "github.com/apache/dubbo-go/protocol" ) -// Authenticator +// Authenticator defines how an Authenticator works. +// Custom Authenticator must be set by calling auth.SetAuthenticator before use. type Authenticator interface { - // Sign - // give a sign to request + // Sign adds signature to the invocation Sign(protocol.Invocation, *common.URL) error - // Authenticate - // verify the signature of the request is valid or not + // Authenticate verifies the signature of the request Authenticate(protocol.Invocation, *common.URL) error } diff --git a/filter/filter.go b/filter/filter.go index c069510498c7ac68b2bb2169dfe7132a4ef63229..d20ca72c345c6812f4bce6df5dbaf683429a9874 100644 --- a/filter/filter.go +++ b/filter/filter.go @@ -24,9 +24,11 @@ import ( "github.com/apache/dubbo-go/protocol" ) -// Filter +// Filter interface defines the functions of a filter // Extension - Filter type Filter interface { + // Invoke is the core function of a filter, it determins the process of the filter Invoke(context.Context, protocol.Invoker, protocol.Invocation) protocol.Result + // OnResponse updates the results from Invoke and then returns the modified results. OnResponse(context.Context, protocol.Result, protocol.Invoker, protocol.Invocation) protocol.Result } diff --git a/filter/filter_impl/active_filter.go b/filter/filter_impl/active_filter.go index 23f2c8e25609dff89392107251715fe6f5175f09..795de968b57207830cc15fc8a0476bfdc3d2cb43 100644 --- a/filter/filter_impl/active_filter.go +++ b/filter/filter_impl/active_filter.go @@ -39,11 +39,11 @@ func init() { extension.SetFilter(active, GetActiveFilter) } -// ActiveFilter ... +// ActiveFilter tracks the requests status type ActiveFilter struct { } -// Invoke ... +// Invoke starts to record the requests status func (ef *ActiveFilter) Invoke(ctx context.Context, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result { logger.Infof("invoking active filter. %v,%v", invocation.MethodName(), len(invocation.Arguments())) invocation.(*invocation2.RPCInvocation).SetAttachments(dubboInvokeStartTime, strconv.FormatInt(protocol.CurrentTimeMillis(), 10)) @@ -51,7 +51,7 @@ func (ef *ActiveFilter) Invoke(ctx context.Context, invoker protocol.Invoker, in return invoker.Invoke(ctx, invocation) } -// OnResponse ... +// OnResponse update the active count base on the request result. func (ef *ActiveFilter) OnResponse(ctx context.Context, result protocol.Result, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result { startTime, err := strconv.ParseInt(invocation.(*invocation2.RPCInvocation).AttachmentsByKey(dubboInvokeStartTime, "0"), 10, 64) if err != nil { @@ -64,7 +64,7 @@ func (ef *ActiveFilter) OnResponse(ctx context.Context, result protocol.Result, return result } -// GetActiveFilter ... +// GetActiveFilter creates ActiveFilter instance func GetActiveFilter() filter.Filter { return &ActiveFilter{} } diff --git a/filter/filter_impl/auth/accesskey_storage.go b/filter/filter_impl/auth/accesskey_storage.go index 5adb9d9ee37329228d1d02dc8802deeede68d327..90d3efb5ad897b874c89745740637804808b5133 100644 --- a/filter/filter_impl/auth/accesskey_storage.go +++ b/filter/filter_impl/auth/accesskey_storage.go @@ -25,13 +25,11 @@ import ( "github.com/apache/dubbo-go/protocol" ) -// DefaultAccesskeyStorage -// The default implementation of AccesskeyStorage +// DefaultAccesskeyStorage is the default implementation of AccesskeyStorage type DefaultAccesskeyStorage struct { } -// GetAccessKeyPair -// get AccessKeyPair from url by the key "accessKeyId" and "secretAccessKey" +// GetAccessKeyPair retrieves AccessKeyPair from url by the key "accessKeyId" and "secretAccessKey" func (storage *DefaultAccesskeyStorage) GetAccessKeyPair(invocation protocol.Invocation, url *common.URL) *filter.AccessKeyPair { return &filter.AccessKeyPair{ AccessKey: url.GetParam(constant.ACCESS_KEY_ID_KEY, ""), @@ -43,6 +41,7 @@ func init() { extension.SetAccesskeyStorages(constant.DEFAULT_ACCESS_KEY_STORAGE, GetDefaultAccesskeyStorage) } +// GetDefaultAccesskeyStorage initiates an empty DefaultAccesskeyStorage func GetDefaultAccesskeyStorage() filter.AccessKeyStorage { return &DefaultAccesskeyStorage{} } diff --git a/filter/filter_impl/auth/consumer_sign.go b/filter/filter_impl/auth/consumer_sign.go index 062744771acf8ccd505265875a103d24afeb06af..945cf3e6e7e728042b5422174162dd5aded50361 100644 --- a/filter/filter_impl/auth/consumer_sign.go +++ b/filter/filter_impl/auth/consumer_sign.go @@ -29,8 +29,7 @@ import ( "github.com/apache/dubbo-go/protocol" ) -// ConsumerSignFilter -// This filter is working for signing the request on consumer side +// ConsumerSignFilter signs the request on consumer side type ConsumerSignFilter struct { } @@ -38,6 +37,7 @@ func init() { extension.SetFilter(constant.CONSUMER_SIGN_FILTER, getConsumerSignFilter) } +// Invoke retrieves the configured Authenticator to add signature to invocation func (csf *ConsumerSignFilter) Invoke(ctx context.Context, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result { logger.Infof("invoking ConsumerSign filter.") url := invoker.GetUrl() @@ -52,6 +52,7 @@ func (csf *ConsumerSignFilter) Invoke(ctx context.Context, invoker protocol.Invo return invoker.Invoke(ctx, invocation) } +// OnResponse dummy process, returns the result directly func (csf *ConsumerSignFilter) OnResponse(ctx context.Context, result protocol.Result, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result { return result } diff --git a/filter/filter_impl/auth/default_authenticator.go b/filter/filter_impl/auth/default_authenticator.go index 2b8d55927807407f350ecc6cfc28b6913a6d1a81..5b86fc148e42b6364bcb0752c31bfbbc3cfa2b9d 100644 --- a/filter/filter_impl/auth/default_authenticator.go +++ b/filter/filter_impl/auth/default_authenticator.go @@ -37,13 +37,11 @@ func init() { extension.SetAuthenticator(constant.DEFAULT_AUTHENTICATOR, GetDefaultAuthenticator) } -// DefaultAuthenticator -// The default implemetation of Authenticator +// DefaultAuthenticator is the default implementation of Authenticator type DefaultAuthenticator struct { } -// Sign -// add the signature for the invocation +// Sign adds the signature to the invocation func (authenticator *DefaultAuthenticator) Sign(invocation protocol.Invocation, url *common.URL) error { currentTimeMillis := strconv.Itoa(int(time.Now().Unix() * 1000)) @@ -84,8 +82,7 @@ func getSignature(url *common.URL, invocation protocol.Invocation, secrectKey st return signature, nil } -// Authenticate -// This method verifies whether the signature sent by the requester is correct +// Authenticate verifies whether the signature sent by the requester is correct func (authenticator *DefaultAuthenticator) Authenticate(invocation protocol.Invocation, url *common.URL) error { accessKeyId := invocation.AttachmentsByKey(constant.AK_KEY, "") @@ -122,6 +119,7 @@ func getAccessKeyPair(invocation protocol.Invocation, url *common.URL) (*filter. } } +// GetDefaultAuthenticator creates an empty DefaultAuthenticator instance func GetDefaultAuthenticator() filter.Authenticator { return &DefaultAuthenticator{} } diff --git a/filter/filter_impl/auth/provider_auth.go b/filter/filter_impl/auth/provider_auth.go index 0d5772e5508894111a88443bfe2d1b02ebfac54a..d5f5db300d4e7c94978d5d52e32f741f7d27bb48 100644 --- a/filter/filter_impl/auth/provider_auth.go +++ b/filter/filter_impl/auth/provider_auth.go @@ -29,8 +29,7 @@ import ( "github.com/apache/dubbo-go/protocol" ) -// ProviderAuthFilter -// This filter is used to verify the correctness of the signature on provider side +// ProviderAuthFilter verifies the correctness of the signature on provider side type ProviderAuthFilter struct { } @@ -38,6 +37,7 @@ func init() { extension.SetFilter(constant.PROVIDER_AUTH_FILTER, getProviderAuthFilter) } +// Invoke retrieves the configured Authenticator to verify the signature in an invocation func (paf *ProviderAuthFilter) Invoke(ctx context.Context, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result { logger.Infof("invoking providerAuth filter.") url := invoker.GetUrl() @@ -55,6 +55,7 @@ func (paf *ProviderAuthFilter) Invoke(ctx context.Context, invoker protocol.Invo return invoker.Invoke(ctx, invocation) } +// OnResponse dummy process, returns the result directly func (paf *ProviderAuthFilter) OnResponse(ctx context.Context, result protocol.Result, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result { return result } diff --git a/filter/filter_impl/auth/sign_util.go b/filter/filter_impl/auth/sign_util.go index 043a549a849dde66712e1bef389dd91a024660df..45170bb8117284275a87a3a57d14ce68d6cc4e9c 100644 --- a/filter/filter_impl/auth/sign_util.go +++ b/filter/filter_impl/auth/sign_util.go @@ -26,12 +26,12 @@ import ( "strings" ) -// Sign -// get a signature string with given information, such as metadata or parameters +// Sign gets a signature string with given bytes func Sign(metadata, key string) string { return doSign([]byte(metadata), key) } +// SignWithParams returns a signature with giving params and metadata. func SignWithParams(params []interface{}, metadata, key string) (string, error) { if params == nil || len(params) == 0 { return Sign(metadata, key), nil @@ -61,6 +61,7 @@ func doSign(bytes []byte, key string) string { return base64.URLEncoding.EncodeToString(signature) } +// IsEmpty verify whether the inputted string is empty func IsEmpty(s string, allowSpace bool) bool { if len(s) == 0 { return true diff --git a/filter/filter_impl/echo_filter.go b/filter/filter_impl/echo_filter.go index a12800a21a8ebe4545b4a8b5bd0f8a30c1462105..7da5ec7029ea698b1bf1a14ad36123fbec3aacf7 100644 --- a/filter/filter_impl/echo_filter.go +++ b/filter/filter_impl/echo_filter.go @@ -38,13 +38,13 @@ func init() { extension.SetFilter(ECHO, GetFilter) } -// EchoFilter +// EchoFilter health check // RPCService need a Echo method in consumer, if you want to use EchoFilter // eg: // Echo func(ctx context.Context, arg interface{}, rsp *Xxx) error type EchoFilter struct{} -// Invoke ... +// Invoke response to the callers with its first argument. func (ef *EchoFilter) Invoke(ctx context.Context, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result { logger.Infof("invoking echo filter.") logger.Debugf("%v,%v", invocation.MethodName(), len(invocation.Arguments())) @@ -58,7 +58,7 @@ func (ef *EchoFilter) Invoke(ctx context.Context, invoker protocol.Invoker, invo return invoker.Invoke(ctx, invocation) } -// OnResponse ... +// OnResponse dummy process, returns the result directly func (ef *EchoFilter) OnResponse(_ context.Context, result protocol.Result, _ protocol.Invoker, _ protocol.Invocation) protocol.Result { diff --git a/filter/filter_impl/execute_limit_filter.go b/filter/filter_impl/execute_limit_filter.go index 434c378045456eb13317e0a48630ebd33f244c05..bfc5096ca089867f6e6234089e387d3f9b48a3aa 100644 --- a/filter/filter_impl/execute_limit_filter.go +++ b/filter/filter_impl/execute_limit_filter.go @@ -45,9 +45,8 @@ func init() { extension.SetFilter(name, GetExecuteLimitFilter) } +// ExecuteLimitFilter will limit the number of in-progress request and it's thread-safe. /** - * ExecuteLimitFilter - * The filter will limit the number of in-progress request and it's thread-safe. * example: * "UserProvider": * registry: "hangzhouzk" @@ -80,7 +79,7 @@ type ExecuteState struct { concurrentCount int64 } -// Invoke ... +// Invoke judges whether the current processing requests over the threshold func (ef *ExecuteLimitFilter) Invoke(ctx context.Context, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result { methodConfigPrefix := "methods." + invocation.MethodName() + "." ivkURL := invoker.GetUrl() @@ -122,7 +121,7 @@ func (ef *ExecuteLimitFilter) Invoke(ctx context.Context, invoker protocol.Invok return invoker.Invoke(ctx, invocation) } -// OnResponse ... +// OnResponse dummy process, returns the result directly func (ef *ExecuteLimitFilter) OnResponse(_ context.Context, result protocol.Result, _ protocol.Invoker, _ protocol.Invocation) protocol.Result { return result } @@ -138,7 +137,7 @@ func (state *ExecuteState) decrease() { var executeLimitOnce sync.Once var executeLimitFilter *ExecuteLimitFilter -// GetExecuteLimitFilter ... +// GetExecuteLimitFilter returns the singleton ExecuteLimitFilter instance func GetExecuteLimitFilter() filter.Filter { executeLimitOnce.Do(func() { executeLimitFilter = &ExecuteLimitFilter{ diff --git a/filter/filter_impl/generic_filter.go b/filter/filter_impl/generic_filter.go index 9bc131ef8903942b84df2b8fc14fd11143d1a7b6..3f4d714e6b0cbdf48f5e1afce3222a18857041f9 100644 --- a/filter/filter_impl/generic_filter.go +++ b/filter/filter_impl/generic_filter.go @@ -50,7 +50,7 @@ func init() { // GenericFilter ... type GenericFilter struct{} -// Invoke ... +// Invoke turns the parameters to map for generic method func (ef *GenericFilter) Invoke(ctx context.Context, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result { if invocation.MethodName() == constant.GENERIC && len(invocation.Arguments()) == 3 { oldArguments := invocation.Arguments() @@ -73,13 +73,13 @@ func (ef *GenericFilter) Invoke(ctx context.Context, invoker protocol.Invoker, i return invoker.Invoke(ctx, invocation) } -// OnResponse ... +// OnResponse dummy process, returns the result directly func (ef *GenericFilter) OnResponse(_ context.Context, result protocol.Result, _ protocol.Invoker, _ protocol.Invocation) protocol.Result { return result } -// GetGenericFilter ... +// GetGenericFilter returns GenericFilter instance func GetGenericFilter() filter.Filter { return &GenericFilter{} } diff --git a/filter/filter_impl/graceful_shutdown_filter.go b/filter/filter_impl/graceful_shutdown_filter.go index 95e625b2d56895a4d57823e4e0e2e7d1d5e90a08..4a4e8ce466edabe82815b99244404ac024d73b26 100644 --- a/filter/filter_impl/graceful_shutdown_filter.go +++ b/filter/filter_impl/graceful_shutdown_filter.go @@ -53,6 +53,7 @@ type gracefulShutdownFilter struct { shutdownConfig *config.ShutdownConfig } +// Invoke adds the requests count and block the new requests if application is closing func (gf *gracefulShutdownFilter) Invoke(ctx context.Context, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result { if gf.rejectNewRequest() { logger.Info("The application is closing, new request will be rejected.") @@ -62,6 +63,7 @@ func (gf *gracefulShutdownFilter) Invoke(ctx context.Context, invoker protocol.I return invoker.Invoke(ctx, invocation) } +// OnResponse reduces the number of active processes then return the process result func (gf *gracefulShutdownFilter) OnResponse(ctx context.Context, result protocol.Result, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result { atomic.AddInt32(&gf.activeCount, -1) // although this isn't thread safe, it won't be a problem if the gf.rejectNewRequest() is true. diff --git a/filter/filter_impl/hystrix_filter.go b/filter/filter_impl/hystrix_filter.go index 4c872bed3e7fef8eca47f51422525a4918d6c1d8..711ef71c44192c5a1d76783a3b3d4cbd0b97632c 100644 --- a/filter/filter_impl/hystrix_filter.go +++ b/filter/filter_impl/hystrix_filter.go @@ -55,14 +55,14 @@ var ( //The filter in the server end of dubbo-go can't get the invoke result for now, //this filter ONLY works in CLIENT end (consumer side) temporarily -//Only after the callService logic is integrated into the filter chain of server end can this filter be used, +//Only after the callService logic is integrated into the filter chain of server end then the filter can be used, //which will be done soon func init() { extension.SetFilter(HYSTRIX_CONSUMER, GetHystrixFilterConsumer) extension.SetFilter(HYSTRIX_PROVIDER, GetHystrixFilterProvider) } -// HystrixFilterError ... +// HystrixFilterError implements error interface type HystrixFilterError struct { err error failByHystrix bool @@ -72,12 +72,12 @@ func (hfError *HystrixFilterError) Error() string { return hfError.err.Error() } -// FailByHystrix ... +// FailByHystrix returns whether the fails causing by Hystrix func (hfError *HystrixFilterError) FailByHystrix() bool { return hfError.failByHystrix } -// NewHystrixFilterError ... +// NewHystrixFilterError return a HystrixFilterError instance func NewHystrixFilterError(err error, failByHystrix bool) error { return &HystrixFilterError{ err: err, @@ -92,7 +92,7 @@ type HystrixFilter struct { ifNewMap sync.Map } -// Invoke ... +// Invoke is an implentation of filter, provides Hystrix pattern latency and fault tolerance func (hf *HystrixFilter) Invoke(ctx context.Context, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result { cmdName := fmt.Sprintf("%s&method=%s", invoker.GetUrl().Key(), invocation.MethodName()) @@ -154,12 +154,12 @@ func (hf *HystrixFilter) Invoke(ctx context.Context, invoker protocol.Invoker, i return result } -// OnResponse ... +// OnResponse dummy process, returns the result directly func (hf *HystrixFilter) OnResponse(ctx context.Context, result protocol.Result, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result { return result } -// GetHystrixFilterConsumer ... +// GetHystrixFilterConsumer returns HystrixFilter instance for consumer func GetHystrixFilterConsumer() filter.Filter { //When first called, load the config in consumerConfigOnce.Do(func() { @@ -170,7 +170,7 @@ func GetHystrixFilterConsumer() filter.Filter { return &HystrixFilter{COrP: true} } -// GetHystrixFilterProvider ... +// GetHystrixFilterProvider returns HystrixFilter instance for provider func GetHystrixFilterProvider() filter.Filter { providerConfigOnce.Do(func() { if err := initHystrixConfigProvider(); err != nil { diff --git a/filter/filter_impl/token_filter.go b/filter/filter_impl/token_filter.go index 8ec3929b6ddc8dcfa430204cd22d2f6d297c59d3..23742c66e94d9ecfc09d004441a54aad86ef049e 100644 --- a/filter/filter_impl/token_filter.go +++ b/filter/filter_impl/token_filter.go @@ -42,10 +42,10 @@ func init() { extension.SetFilter(TOKEN, GetTokenFilter) } -// TokenFilter ... +// TokenFilter will verify if the token is valid type TokenFilter struct{} -// Invoke ... +// Invoke verifies the incoming token with the service configured token func (tf *TokenFilter) Invoke(ctx context.Context, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result { invokerTkn := invoker.GetUrl().GetParam(constant.TOKEN_KEY, "") if len(invokerTkn) > 0 { @@ -61,7 +61,7 @@ func (tf *TokenFilter) Invoke(ctx context.Context, invoker protocol.Invoker, inv return invoker.Invoke(ctx, invocation) } -// OnResponse ... +// OnResponse dummy process, returns the result directly func (tf *TokenFilter) OnResponse(ctx context.Context, result protocol.Result, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result { return result } diff --git a/filter/filter_impl/tps/tps_limit_fix_window_strategy.go b/filter/filter_impl/tps/tps_limit_fix_window_strategy.go index a9c2ac15a417ffa6ff8f5b8d78d5c6a94877db30..7419a4576122d4db334969b0711666b5b2816e60 100644 --- a/filter/filter_impl/tps/tps_limit_fix_window_strategy.go +++ b/filter/filter_impl/tps/tps_limit_fix_window_strategy.go @@ -39,8 +39,8 @@ func init() { extension.SetTpsLimitStrategy(constant.DEFAULT_KEY, creator) } +// FixedWindowTpsLimitStrategyImpl implements the TPS limit strategy base on requests count during the interval /** - * FixedWindowTpsLimitStrategyImpl * It's the same as default implementation in Java * It's not a thread-safe implementation. * It you want to use the thread-safe implementation, please use ThreadSafeFixedWindowTpsLimitStrategyImpl @@ -65,7 +65,8 @@ type FixedWindowTpsLimitStrategyImpl struct { timestamp int64 } -// IsAllowable ... +// IsAllowable determines if the requests over the TPS limit within the interval. +// It is not thread-safe. func (impl *FixedWindowTpsLimitStrategyImpl) IsAllowable() bool { current := time.Now().UnixNano() @@ -82,6 +83,7 @@ func (impl *FixedWindowTpsLimitStrategyImpl) IsAllowable() bool { type fixedWindowStrategyCreator struct{} +// Create returns a FixedWindowTpsLimitStrategyImpl instance with pre-configured limit rate and interval func (creator *fixedWindowStrategyCreator) Create(rate int, interval int) filter.TpsLimitStrategy { return &FixedWindowTpsLimitStrategyImpl{ rate: int32(rate), diff --git a/filter/filter_impl/tps/tps_limit_sliding_window_strategy.go b/filter/filter_impl/tps/tps_limit_sliding_window_strategy.go index a781cc7bfbf297d0b9cf84ca0aa9dcfbbef7e14b..cbbba19fff65be222cb895dcbe9b2e4d02082985 100644 --- a/filter/filter_impl/tps/tps_limit_sliding_window_strategy.go +++ b/filter/filter_impl/tps/tps_limit_sliding_window_strategy.go @@ -32,8 +32,8 @@ func init() { extension.SetTpsLimitStrategy("slidingWindow", &slidingWindowStrategyCreator{}) } +// SlidingWindowTpsLimitStrategyImpl implements a thread-safe TPS limit strategy base on requests count. /** - * SlidingWindowTpsLimitStrategyImpl * it's thread-safe. * "UserProvider": * registry: "hangzhouzk" @@ -54,7 +54,8 @@ type SlidingWindowTpsLimitStrategyImpl struct { queue *list.List } -// IsAllowable ... +// IsAllowable determins whether the number of requests within the time window overs the threshold +// It is thread-safe. func (impl *SlidingWindowTpsLimitStrategyImpl) IsAllowable() bool { impl.mutex.Lock() defer impl.mutex.Unlock() @@ -84,6 +85,7 @@ func (impl *SlidingWindowTpsLimitStrategyImpl) IsAllowable() bool { type slidingWindowStrategyCreator struct{} +// Create returns SlidingWindowTpsLimitStrategyImpl instance with configured limit rate and interval func (creator *slidingWindowStrategyCreator) Create(rate int, interval int) filter.TpsLimitStrategy { return &SlidingWindowTpsLimitStrategyImpl{ rate: rate, diff --git a/filter/filter_impl/tps/tps_limit_thread_safe_fix_window_strategy.go b/filter/filter_impl/tps/tps_limit_thread_safe_fix_window_strategy.go index 16624836e6397df5adda3f2aa5a80966721a97fb..f78cd8211cd076dcab84759e2bf784d080c72a1c 100644 --- a/filter/filter_impl/tps/tps_limit_thread_safe_fix_window_strategy.go +++ b/filter/filter_impl/tps/tps_limit_thread_safe_fix_window_strategy.go @@ -32,10 +32,9 @@ func init() { }) } +// ThreadSafeFixedWindowTpsLimitStrategyImpl is the thread-safe implementation. +// It's also a thread-safe decorator of FixedWindowTpsLimitStrategyImpl /** - * ThreadSafeFixedWindowTpsLimitStrategyImpl - * it's the thread-safe implementation. - * Also, it's a thread-safe decorator of FixedWindowTpsLimitStrategyImpl * "UserProvider": * registry: "hangzhouzk" * protocol : "dubbo" @@ -53,7 +52,7 @@ type ThreadSafeFixedWindowTpsLimitStrategyImpl struct { fixedWindow *FixedWindowTpsLimitStrategyImpl } -// IsAllowable ... +// IsAllowable implements thread-safe then run the FixedWindowTpsLimitStrategy func (impl *ThreadSafeFixedWindowTpsLimitStrategyImpl) IsAllowable() bool { impl.mutex.Lock() defer impl.mutex.Unlock() @@ -64,6 +63,7 @@ type threadSafeFixedWindowStrategyCreator struct { fixedWindowStrategyCreator *fixedWindowStrategyCreator } +// Create returns ThreadSafeFixedWindowTpsLimitStrategyImpl instance func (creator *threadSafeFixedWindowStrategyCreator) Create(rate int, interval int) filter.TpsLimitStrategy { fixedWindowStrategy := creator.fixedWindowStrategyCreator.Create(rate, interval).(*FixedWindowTpsLimitStrategyImpl) return &ThreadSafeFixedWindowTpsLimitStrategyImpl{ diff --git a/filter/filter_impl/tps/tps_limiter_method_service.go b/filter/filter_impl/tps/tps_limiter_method_service.go index 2d44c688ebd460f60a49da0f148fd7c6e2b79f50..5761579a38a22500d54193a9564170cc0215cf0f 100644 --- a/filter/filter_impl/tps/tps_limiter_method_service.go +++ b/filter/filter_impl/tps/tps_limiter_method_service.go @@ -44,9 +44,8 @@ func init() { extension.SetTpsLimiter(name, GetMethodServiceTpsLimiter) } +// MethodServiceTpsLimiterImpl allows developer to config both method-level and service-level tps limiter. /** - * MethodServiceTpsLimiterImpl - * This implementation allows developer to config both method-level and service-level tps limiter. * for example: * "UserProvider": * registry: "hangzhouzk" diff --git a/filter/filter_impl/tps_limit_filter.go b/filter/filter_impl/tps_limit_filter.go index fa78288f9678d67d0eb0d025a83b75493f7fda80..ea1e3bc15e1952799227d712db114ff790527720 100644 --- a/filter/filter_impl/tps_limit_filter.go +++ b/filter/filter_impl/tps_limit_filter.go @@ -39,8 +39,8 @@ func init() { extension.SetFilter(TpsLimitFilterKey, GetTpsLimitFilter) } +// TpsLimitFilter filters the requests by TPS /** - * TpsLimitFilter * if you wish to use the TpsLimiter, please add the configuration into your service provider configuration: * for example: * "UserProvider": @@ -56,7 +56,7 @@ func init() { type TpsLimitFilter struct { } -// Invoke ... +// Invoke gets the configured limter to impose TPS limiting func (t TpsLimitFilter) Invoke(ctx context.Context, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result { url := invoker.GetUrl() tpsLimiter := url.GetParam(constant.TPS_LIMITER_KEY, "") @@ -72,13 +72,13 @@ func (t TpsLimitFilter) Invoke(ctx context.Context, invoker protocol.Invoker, in return invoker.Invoke(ctx, invocation) } -// OnResponse ... +// OnResponse dummy process, returns the result directly func (t TpsLimitFilter) OnResponse(_ context.Context, result protocol.Result, _ protocol.Invoker, _ protocol.Invocation) protocol.Result { return result } -// GetTpsLimitFilter ... +// GetTpsLimitFilter returns an TpsLimitFilter instance. func GetTpsLimitFilter() filter.Filter { return &TpsLimitFilter{} } diff --git a/filter/handler/rejected_execution_handler_only_log.go b/filter/handler/rejected_execution_handler_only_log.go index fe9cf4869f16e1d7c136e7f48e4138d046fcb057..52ac1765f78172c0062de8884198e759b8d494ca 100644 --- a/filter/handler/rejected_execution_handler_only_log.go +++ b/filter/handler/rejected_execution_handler_only_log.go @@ -44,8 +44,8 @@ func init() { var onlyLogHandlerInstance *OnlyLogRejectedExecutionHandler var onlyLogHandlerOnce sync.Once +// OnlyLogRejectedExecutionHandler implements the RejectedExecutionHandler /** - * OnlyLogRejectedExecutionHandler * This implementation only logs the invocation info. * it always return en error inside the result. * "UserProvider": diff --git a/filter/rejected_execution_handler.go b/filter/rejected_execution_handler.go index d02481b98d2937ac58d277becdb1240b8a4e9b0f..3d1e1c1e641a836411ce0f71f97acf5d5a55f6d1 100644 --- a/filter/rejected_execution_handler.go +++ b/filter/rejected_execution_handler.go @@ -22,8 +22,8 @@ import ( "github.com/apache/dubbo-go/protocol" ) +// RejectedExecutionHandler defines the handler to handle exceptions from invoking filters. /** - * RejectedExecutionHandler * If the invocation cannot pass any validation in filter, like ExecuteLimitFilter and TpsLimitFilter, * the implementation will be used. * The common case is that sometimes you want to return the default value when the request was rejected. diff --git a/filter/tps_limit_strategy.go b/filter/tps_limit_strategy.go index e194f1da06b0599464f0c66f6b7747fc78fbedce..2ee876a0b340ed1f87b94c35b149b548371e2bf9 100644 --- a/filter/tps_limit_strategy.go +++ b/filter/tps_limit_strategy.go @@ -17,8 +17,8 @@ package filter +// TpsLimitStrategy defines how to do the TPS limiting in method level. /* - * TpsLimitStrategy * please register your implementation by invoking SetTpsLimitStrategy * "UserProvider": * registry: "hangzhouzk" @@ -37,7 +37,7 @@ type TpsLimitStrategy interface { IsAllowable() bool } -// TpsLimitStrategyCreator, the creator abstraction for TpsLimitStrategy +// TpsLimitStrategyCreator is the creator abstraction for TpsLimitStrategy type TpsLimitStrategyCreator interface { // Create will create an instance of TpsLimitStrategy // It will be a little hard to understand this method. diff --git a/filter/tps_limiter.go b/filter/tps_limiter.go index 531eb098232cd34a467d71882b29858c07f88aef..8385d7b5d84a420b54df6bf51e32a35d17e1b249 100644 --- a/filter/tps_limiter.go +++ b/filter/tps_limiter.go @@ -22,8 +22,8 @@ import ( "github.com/apache/dubbo-go/protocol" ) +// TpsLimiter defines the Limiter that judge if the TPS overs the threshold /* - * TpsLimiter * please register your implementation by invoking SetTpsLimiter * The usage, for example: * "UserProvider": diff --git a/metadata/identifier/base_metadata_identifier.go b/metadata/identifier/base_metadata_identifier.go index a314671055be523844fd7d8f9589b8b6031632bc..5f3df4c607e69d2b56e1258d081c148524cd7aca 100644 --- a/metadata/identifier/base_metadata_identifier.go +++ b/metadata/identifier/base_metadata_identifier.go @@ -25,11 +25,13 @@ import ( "github.com/apache/dubbo-go/common/constant" ) +// BaseMetadataIdentifier defined for description the Metadata base identify type BaseMetadataIdentifier interface { getFilePathKey(params ...string) string getIdentifierKey(params ...string) string } +// BaseMetadataIdentifier is the base implement of BaseMetadataIdentifier interface type BaseServiceMetadataIdentifier struct { serviceInterface string version string @@ -37,7 +39,7 @@ type BaseServiceMetadataIdentifier struct { side string } -// joinParams... +// joinParams will join the specified char in slice, and return a string func joinParams(joinChar string, params []string) string { var joinedStr string for _, param := range params { @@ -47,7 +49,7 @@ func joinParams(joinChar string, params []string) string { return joinedStr } -// getIdentifierKey... +// getIdentifierKey returns string that format is service:Version:Group:Side:param1:param2... func (mdi *BaseServiceMetadataIdentifier) getIdentifierKey(params ...string) string { return mdi.serviceInterface + constant.KEY_SEPARATOR + mdi.version + @@ -56,7 +58,7 @@ func (mdi *BaseServiceMetadataIdentifier) getIdentifierKey(params ...string) str joinParams(constant.KEY_SEPARATOR, params) } -// getFilePathKey... +// getFilePathKey returns string that format is metadata/path/Version/Group/Side/param1/param2... func (mdi *BaseServiceMetadataIdentifier) getFilePathKey(params ...string) string { path := serviceToPath(mdi.serviceInterface) @@ -69,7 +71,6 @@ func (mdi *BaseServiceMetadataIdentifier) getFilePathKey(params ...string) strin } -// serviceToPath... func serviceToPath(serviceInterface string) string { if serviceInterface == constant.ANY_VALUE { return "" @@ -83,7 +84,6 @@ func serviceToPath(serviceInterface string) string { } -//withPathSeparator... func withPathSeparator(path string) string { if len(path) != 0 { path = constant.PATH_SEPARATOR + path diff --git a/metadata/identifier/metadata_identifier.go b/metadata/identifier/metadata_identifier.go index f3df8f36546093a826279c4e9ec1546f78d444bd..7e72c10da9c088ca167fa4fbc4dcb57f44b8c06d 100644 --- a/metadata/identifier/metadata_identifier.go +++ b/metadata/identifier/metadata_identifier.go @@ -17,17 +17,18 @@ package identifier +// MetadataIdentifier is inherit baseMetaIdentifier with Application name type MetadataIdentifier struct { application string BaseMetadataIdentifier } -// getIdentifierKey... +// GetIdentifierKey returns string that format is service:Version:Group:Side:Application func (mdi *MetadataIdentifier) getIdentifierKey(params ...string) string { return mdi.BaseMetadataIdentifier.getIdentifierKey(mdi.application) } -// getIdentifierKey... +// GetFilePathKey returns string that format is metadata/path/Version/Group/Side/Application func (mdi *MetadataIdentifier) getFilePathKey(params ...string) string { return mdi.BaseMetadataIdentifier.getFilePathKey(mdi.application) } diff --git a/metadata/identifier/service_metadata_identifier.go b/metadata/identifier/service_metadata_identifier.go index 373df0130dd1f87e3175918bde50060c4be89616..ccc149f7306c125b19a25373d4da660a154cc84e 100644 --- a/metadata/identifier/service_metadata_identifier.go +++ b/metadata/identifier/service_metadata_identifier.go @@ -21,18 +21,19 @@ import ( "github.com/apache/dubbo-go/common/constant" ) +// ServiceMetadataIdentifier is inherit baseMetaIdentifier with service params: Revision and Protocol type ServiceMetadataIdentifier struct { revision string protocol string BaseMetadataIdentifier } -// getIdentifierKey... +// GetIdentifierKey returns string that format is service:Version:Group:Side:Protocol:"revision"+Revision func (mdi *ServiceMetadataIdentifier) getIdentifierKey(params ...string) string { return mdi.BaseMetadataIdentifier.getIdentifierKey(mdi.protocol + constant.KEY_REVISON_PREFIX + mdi.revision) } -// getIdentifierKey... +// GetFilePathKey returns string that format is metadata/path/Version/Group/Side/Protocol/"revision"+Revision func (mdi *ServiceMetadataIdentifier) getFilePathKey(params ...string) string { return mdi.BaseMetadataIdentifier.getFilePathKey(mdi.protocol + constant.KEY_REVISON_PREFIX + mdi.revision) } diff --git a/metadata/identifier/subscribe_metadata_identifier.go b/metadata/identifier/subscribe_metadata_identifier.go index 321a216a3e3ad3f2390ab832782924a81e226160..38f3ebbd462338b581d83cd19403a00a5064b5a4 100644 --- a/metadata/identifier/subscribe_metadata_identifier.go +++ b/metadata/identifier/subscribe_metadata_identifier.go @@ -17,17 +17,18 @@ package identifier +// SubscriberMetadataIdentifier is inherit baseMetaIdentifier with service params: Revision type SubscriberMetadataIdentifier struct { revision string BaseMetadataIdentifier } -// getIdentifierKey... +// GetIdentifierKey returns string that format is service:Version:Group:Side:Revision func (mdi *SubscriberMetadataIdentifier) getIdentifierKey(params ...string) string { return mdi.BaseMetadataIdentifier.getIdentifierKey(mdi.revision) } -// getIdentifierKey... +// GetFilePathKey returns string that format is metadata/path/Version/Group/Side/Revision func (mdi *SubscriberMetadataIdentifier) getFilePathKey(params ...string) string { return mdi.BaseMetadataIdentifier.getFilePathKey(mdi.revision) } diff --git a/metadata/service.go b/metadata/service.go index d85703c95a57183d5c0a5b2445839e946dc6a59b..89df68fb313b1abe63082c0c220b0114c11fca19 100644 --- a/metadata/service.go +++ b/metadata/service.go @@ -22,6 +22,9 @@ import ( gxset "github.com/dubbogo/gost/container/set" ) +// Metadata service is a built-in service around the metadata of Dubbo services, +// whose interface is provided by Dubbo Framework and exported automatically before subscription after other services exporting, +// which may be used for Dubbo subscribers and admin. type MetadataService interface { ServiceName() string ExportURL(url *common.URL) bool diff --git a/protocol/dubbo/client.go b/protocol/dubbo/client.go index e6ffa64d80a327517bcd5b6fb9ff2efdc9aed337..6d1b771bf4108d17372e0ceb5ca818323278afd2 100644 --- a/protocol/dubbo/client.go +++ b/protocol/dubbo/client.go @@ -111,7 +111,7 @@ func setClientGrpool() { } } -// Options ... +// Options is option for create dubbo client type Options struct { // connect timeout ConnectTimeout time.Duration diff --git a/protocol/dubbo/codec.go b/protocol/dubbo/codec.go index 620a57d4a7f09da33f752b4890692d6102eb95df..1f7d107544a06d0ef83bcb54ff6f03daf2dc517b 100644 --- a/protocol/dubbo/codec.go +++ b/protocol/dubbo/codec.go @@ -65,6 +65,7 @@ type DubboPackage struct { Err error } +// String prints dubbo package detail include header銆乸ath銆乥ody etc. func (p DubboPackage) String() string { return fmt.Sprintf("DubboPackage: Header-%v, Path-%v, Body-%v", p.Header, p.Service, p.Body) } diff --git a/protocol/dubbo/config.go b/protocol/dubbo/config.go index 6a1daf857a7c54ae2c37a1c85ab17481f6fe6068..635d12109add17cfac1056316c9d53817525fd67 100644 --- a/protocol/dubbo/config.go +++ b/protocol/dubbo/config.go @@ -27,7 +27,7 @@ import ( ) type ( - // GettySessionParam ... + // GettySessionParam is session configuration for getty. GettySessionParam struct { CompressEncoding bool `default:"false" yaml:"compress_encoding" json:"compress_encoding,omitempty"` TcpNoDelay bool `default:"true" yaml:"tcp_no_delay" json:"tcp_no_delay,omitempty"` @@ -47,8 +47,7 @@ type ( SessionName string `default:"rpc" yaml:"session_name" json:"session_name,omitempty"` } - // ServerConfig - //Config holds supported types by the multiconfig package + // ServerConfig holds supported types by the multiconfig package ServerConfig struct { // session SessionTimeout string `default:"60s" yaml:"session_timeout" json:"session_timeout,omitempty"` @@ -64,8 +63,7 @@ type ( GettySessionParam GettySessionParam `required:"true" yaml:"getty_session_param" json:"getty_session_param,omitempty"` } - // ClientConfig - //Config holds supported types by the multiconfig package + // ClientConfig holds supported types by the multiconfig package ClientConfig struct { ReconnectInterval int `default:"0" yaml:"reconnect_interval" json:"reconnect_interval,omitempty"` @@ -94,7 +92,7 @@ type ( } ) -// GetDefaultClientConfig ... +// GetDefaultClientConfig gets client default configuration. func GetDefaultClientConfig() ClientConfig { return ClientConfig{ ReconnectInterval: 0, @@ -122,7 +120,7 @@ func GetDefaultClientConfig() ClientConfig { }} } -// GetDefaultServerConfig ... +// GetDefaultServerConfig gets server default configuration. func GetDefaultServerConfig() ServerConfig { return ServerConfig{ SessionTimeout: "180s", diff --git a/protocol/dubbo/dubbo_protocol.go b/protocol/dubbo/dubbo_protocol.go index b7d0a8a26818bd318a2724d3310d7da23b046fae..9eeefd079279d82241da8e21df5edfe77b8003e0 100644 --- a/protocol/dubbo/dubbo_protocol.go +++ b/protocol/dubbo/dubbo_protocol.go @@ -33,7 +33,7 @@ import ( // dubbo protocol constant const ( - // DUBBO ... + // DUBBO is dubbo protocol name DUBBO = "dubbo" ) diff --git a/protocol/dubbo/listener.go b/protocol/dubbo/listener.go index f57d89d1a716d2a6056e0e4a581926dc237934e4..4834459390f39912f0683dfe52f65faa72b7c26d 100644 --- a/protocol/dubbo/listener.go +++ b/protocol/dubbo/listener.go @@ -41,10 +41,9 @@ import ( "github.com/apache/dubbo-go/protocol/invocation" ) -// todo: WritePkg_Timeout will entry *.yml +// todo: writePkg_Timeout will entry *.yml const ( - // WritePkg_Timeout ... - WritePkg_Timeout = 5 * time.Second + writePkg_Timeout = 5 * time.Second ) var ( @@ -56,10 +55,12 @@ type rpcSession struct { reqNum int32 } +// AddReqNum adds total request number safely func (s *rpcSession) AddReqNum(num int32) { atomic.AddInt32(&s.reqNum, num) } +// GetReqNum gets total request number safely func (s *rpcSession) GetReqNum() int32 { return atomic.LoadInt32(&s.reqNum) } @@ -68,35 +69,35 @@ func (s *rpcSession) GetReqNum() int32 { // RpcClientHandler // ////////////////////////////////////////// -// RpcClientHandler ... +// RpcClientHandler is handler of RPC Client type RpcClientHandler struct { conn *gettyRPCClient } -// NewRpcClientHandler ... +// NewRpcClientHandler creates RpcClientHandler with @gettyRPCClient func NewRpcClientHandler(client *gettyRPCClient) *RpcClientHandler { return &RpcClientHandler{conn: client} } -// OnOpen ... +// OnOpen notified when RPC client session opened func (h *RpcClientHandler) OnOpen(session getty.Session) error { h.conn.addSession(session) return nil } -// OnError ... +// OnError notified when RPC client session got any error func (h *RpcClientHandler) OnError(session getty.Session, err error) { logger.Warnf("session{%s} got error{%v}, will be closed.", session.Stat(), err) h.conn.removeSession(session) } -// OnClose ... +// OnOpen notified when RPC client session closed func (h *RpcClientHandler) OnClose(session getty.Session) { logger.Infof("session{%s} is closing......", session.Stat()) h.conn.removeSession(session) } -// OnMessage ... +// OnMessage notified when RPC client session got any message in connection func (h *RpcClientHandler) OnMessage(session getty.Session, pkg interface{}) { p, ok := pkg.(*DubboPackage) if !ok { @@ -141,7 +142,7 @@ func (h *RpcClientHandler) OnMessage(session getty.Session, pkg interface{}) { } } -// OnCron ... +// OnCron notified when RPC client session got any message in cron job func (h *RpcClientHandler) OnCron(session getty.Session) { clientRpcSession, err := h.conn.getClientRpcSession(session) if err != nil { @@ -163,7 +164,7 @@ func (h *RpcClientHandler) OnCron(session getty.Session) { // RpcServerHandler // ////////////////////////////////////////// -// RpcServerHandler ... +// RpcServerHandler is handler of RPC Server type RpcServerHandler struct { maxSessionNum int sessionTimeout time.Duration @@ -171,7 +172,7 @@ type RpcServerHandler struct { rwlock sync.RWMutex } -// NewRpcServerHandler ... +// NewRpcServerHandler creates RpcServerHandler with @maxSessionNum and @sessionTimeout func NewRpcServerHandler(maxSessionNum int, sessionTimeout time.Duration) *RpcServerHandler { return &RpcServerHandler{ maxSessionNum: maxSessionNum, @@ -180,7 +181,7 @@ func NewRpcServerHandler(maxSessionNum int, sessionTimeout time.Duration) *RpcSe } } -// OnOpen ... +// OnOpen notified when RPC server session opened func (h *RpcServerHandler) OnOpen(session getty.Session) error { var err error h.rwlock.RLock() @@ -199,7 +200,7 @@ func (h *RpcServerHandler) OnOpen(session getty.Session) error { return nil } -// OnError ... +// OnError notified when RPC server session got any error func (h *RpcServerHandler) OnError(session getty.Session, err error) { logger.Warnf("session{%s} got error{%v}, will be closed.", session.Stat(), err) h.rwlock.Lock() @@ -207,7 +208,7 @@ func (h *RpcServerHandler) OnError(session getty.Session, err error) { h.rwlock.Unlock() } -// OnClose ... +// OnOpen notified when RPC server session closed func (h *RpcServerHandler) OnClose(session getty.Session) { logger.Infof("session{%s} is closing......", session.Stat()) h.rwlock.Lock() @@ -215,7 +216,7 @@ func (h *RpcServerHandler) OnClose(session getty.Session) { h.rwlock.Unlock() } -// OnMessage ... +// OnMessage notified when RPC server session got any message in connection func (h *RpcServerHandler) OnMessage(session getty.Session, pkg interface{}) { h.rwlock.Lock() if _, ok := h.sessionMap[session]; ok { @@ -306,7 +307,7 @@ func (h *RpcServerHandler) OnMessage(session getty.Session, pkg interface{}) { reply(session, p, hessian.PackageResponse) } -// OnCron ... +// OnCron notified when RPC server session got any message in cron job func (h *RpcServerHandler) OnCron(session getty.Session) { var ( flag bool @@ -363,7 +364,7 @@ func reply(session getty.Session, req *DubboPackage, tp hessian.PackageType) { resp.Body = nil } - if err := session.WritePkg(resp, WritePkg_Timeout); err != nil { + if err := session.WritePkg(resp, writePkg_Timeout); err != nil { logger.Errorf("WritePkg error: %#v, %#v", perrors.WithStack(err), req.Header) } } diff --git a/protocol/dubbo/pool.go b/protocol/dubbo/pool.go index f0bd09ba7c3392dd1dbe10306c7c70cc0eab8ccb..c9f5e34fadf61fb36e92356f1b1d40fbc67e4c99 100644 --- a/protocol/dubbo/pool.go +++ b/protocol/dubbo/pool.go @@ -319,9 +319,7 @@ func (p *gettyRPCClientPool) getGettyRpcClient(protocol, addr string) (*gettyRPC conn, err := p.get() if err == nil && conn == nil { // create new conn - var rpcClientConn *gettyRPCClient - rpcClientConn, err = newGettyRPCClientConn(p, protocol, addr) - return rpcClientConn, perrors.WithStack(err) + conn, err = newGettyRPCClientConn(p, protocol, addr) } return conn, perrors.WithStack(err) } diff --git a/protocol/grpc/client.go b/protocol/grpc/client.go index 0c7499a179571d623eccc607dd4cc8f1950f3239..a0ab0be80cc905115e675c1c4dea2b1c748f6c09 100644 --- a/protocol/grpc/client.go +++ b/protocol/grpc/client.go @@ -25,27 +25,78 @@ import ( "github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc" "github.com/opentracing/opentracing-go" "google.golang.org/grpc" + "gopkg.in/yaml.v2" ) import ( "github.com/apache/dubbo-go/common" "github.com/apache/dubbo-go/common/constant" + "github.com/apache/dubbo-go/common/logger" "github.com/apache/dubbo-go/config" ) -// Client ... +var ( + clientConf *ClientConfig +) + +func init() { + // load clientconfig from consumer_config + consumerConfig := config.GetConsumerConfig() + + clientConfig := GetClientConfig() + clientConf = &clientConfig + + // check client config and decide whether to use the default config + defer func() { + if clientConf == nil || len(clientConf.ContentSubType) == 0 { + defaultClientConfig := GetDefaultClientConfig() + clientConf = &defaultClientConfig + } + if err := clientConf.Validate(); err != nil { + panic(err) + } + }() + + if consumerConfig.ApplicationConfig == nil { + return + } + protocolConf := config.GetConsumerConfig().ProtocolConf + + if protocolConf == nil { + logger.Info("protocol_conf default use dubbo config") + } else { + grpcConf := protocolConf.(map[interface{}]interface{})[GRPC] + if grpcConf == nil { + logger.Warnf("grpcConf is nil") + return + } + grpcConfByte, err := yaml.Marshal(grpcConf) + if err != nil { + panic(err) + } + err = yaml.Unmarshal(grpcConfByte, clientConf) + if err != nil { + panic(err) + } + } + +} + +// Client is gRPC client include client connection and invoker type Client struct { *grpc.ClientConn invoker reflect.Value } -// NewClient ... +// NewClient creates a new gRPC client. func NewClient(url common.URL) *Client { // if global trace instance was set , it means trace function enabled. If not , will return Nooptracer tracer := opentracing.GlobalTracer() - conn, err := grpc.Dial(url.Location, grpc.WithInsecure(), grpc.WithBlock(), - grpc.WithUnaryInterceptor( - otgrpc.OpenTracingClientInterceptor(tracer, otgrpc.LogPayloads()))) + dailOpts := make([]grpc.DialOption, 0, 4) + dailOpts = append(dailOpts, grpc.WithInsecure(), grpc.WithBlock(), grpc.WithUnaryInterceptor( + otgrpc.OpenTracingClientInterceptor(tracer, otgrpc.LogPayloads())), + grpc.WithDefaultCallOptions(grpc.CallContentSubtype(clientConf.ContentSubType))) + conn, err := grpc.Dial(url.Location, dailOpts...) if err != nil { panic(err) } diff --git a/protocol/grpc/codec.go b/protocol/grpc/codec.go new file mode 100644 index 0000000000000000000000000000000000000000..7235a3941baefcdce5964ae21dbdbfe9d6ca9cc8 --- /dev/null +++ b/protocol/grpc/codec.go @@ -0,0 +1,76 @@ +/* + * 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 grpc + +import ( + "bytes" + "encoding/json" +) + +import ( + "github.com/golang/protobuf/jsonpb" + "github.com/golang/protobuf/proto" + "google.golang.org/grpc/encoding" +) + +const ( + codecJson = "json" + codecProto = "proto" +) + +func init() { + encoding.RegisterCodec(grpcJson{ + Marshaler: jsonpb.Marshaler{ + EmitDefaults: true, + OrigName: true, + }, + }) +} + +type grpcJson struct { + jsonpb.Marshaler + jsonpb.Unmarshaler +} + +// Name implements grpc encoding package Codec interface method, +// returns the name of the Codec implementation. +func (_ grpcJson) Name() string { + return codecJson +} + +// Marshal implements grpc encoding package Codec interface method,returns the wire format of v. +func (j grpcJson) Marshal(v interface{}) (out []byte, err error) { + if pm, ok := v.(proto.Message); ok { + b := new(bytes.Buffer) + err := j.Marshaler.Marshal(b, pm) + if err != nil { + return nil, err + } + return b.Bytes(), nil + } + return json.Marshal(v) +} + +// Unmarshal implements grpc encoding package Codec interface method,Unmarshal parses the wire format into v. +func (j grpcJson) Unmarshal(data []byte, v interface{}) (err error) { + if pm, ok := v.(proto.Message); ok { + b := bytes.NewBuffer(data) + return j.Unmarshaler.Unmarshal(b, pm) + } + return json.Unmarshal(data, v) +} diff --git a/protocol/grpc/config.go b/protocol/grpc/config.go new file mode 100644 index 0000000000000000000000000000000000000000..e8a9baac8999a009bab435a5bd4e70d102f77b56 --- /dev/null +++ b/protocol/grpc/config.go @@ -0,0 +1,65 @@ +/* + * 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 grpc + +import ( + perrors "github.com/pkg/errors" +) + +type ( + // ServerConfig currently is empty struct,for future expansion + ServerConfig struct { + } + + // ClientConfig wrap client call parameters + ClientConfig struct { + // content type, more information refer by https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#requests + ContentSubType string `default:"proto" yaml:"content_sub_type" json:"content_sub_type,omitempty"` + } +) + +// GetDefaultClientConfig return grpc client default call options +func GetDefaultClientConfig() ClientConfig { + return ClientConfig{ + ContentSubType: codecProto, + } +} + +// GetDefaultServerConfig currently return empty struct,for future expansion +func GetDefaultServerConfig() ServerConfig { + return ServerConfig{} +} + +// GetClientConfig return grpc client custom call options +func GetClientConfig() ClientConfig { + return ClientConfig{} +} + +// Validate check if custom config encoding is supported in dubbo grpc +func (c *ClientConfig) Validate() error { + if c.ContentSubType != codecJson && c.ContentSubType != codecProto { + return perrors.Errorf(" dubbo-go grpc codec currently only support proto銆乯son, %s isn't supported,"+ + " please check protocol content_sub_type config", c.ContentSubType) + } + return nil +} + +// Validate currently return empty struct,for future expansion +func (c *ServerConfig) Validate() error { + return nil +} diff --git a/protocol/grpc/grpc_exporter.go b/protocol/grpc/grpc_exporter.go index 0296ad8b5b06b693fd5e0972f18be77a69cd21ed..79962b59e29bb0e3aeb58776f6c26abc2e6832de 100644 --- a/protocol/grpc/grpc_exporter.go +++ b/protocol/grpc/grpc_exporter.go @@ -33,14 +33,14 @@ type GrpcExporter struct { *protocol.BaseExporter } -// NewGrpcExporter ... +// NewGrpcExporter creates a new gRPC exporter func NewGrpcExporter(key string, invoker protocol.Invoker, exporterMap *sync.Map) *GrpcExporter { return &GrpcExporter{ BaseExporter: protocol.NewBaseExporter(key, invoker, exporterMap), } } -// Unexport ... +// Unexport and unregister gRPC service from registry and memory. func (gg *GrpcExporter) Unexport() { serviceId := gg.GetInvoker().GetUrl().GetParam(constant.BEAN_NAME_KEY, "") interfaceName := gg.GetInvoker().GetUrl().GetParam(constant.INTERFACE_KEY, "") diff --git a/protocol/grpc/grpc_invoker.go b/protocol/grpc/grpc_invoker.go index 78439fcd9b7f7d3b845f326bf432ea486855965e..e150d05e6fb39890bd3e355f4042b4ef34db42ed 100644 --- a/protocol/grpc/grpc_invoker.go +++ b/protocol/grpc/grpc_invoker.go @@ -35,8 +35,7 @@ import ( "github.com/apache/dubbo-go/protocol" ) -// ErrNoReply ... -var ErrNoReply = errors.New("request need @response") +var errNoReply = errors.New("request need @response") // GrpcInvoker ... type GrpcInvoker struct { @@ -60,7 +59,7 @@ func (gi *GrpcInvoker) Invoke(ctx context.Context, invocation protocol.Invocatio ) if invocation.Reply() == nil { - result.Err = ErrNoReply + result.Err = errNoReply } in := []reflect.Value{} diff --git a/protocol/grpc/grpc_protocol.go b/protocol/grpc/grpc_protocol.go index cc4aba10bf69f5e80d761649b9830fd61c4084cd..68594a4b35921b6e3b1d59d404ed163025d57a81 100644 --- a/protocol/grpc/grpc_protocol.go +++ b/protocol/grpc/grpc_protocol.go @@ -39,14 +39,14 @@ func init() { var grpcProtocol *GrpcProtocol -// GrpcProtocol ... +// GrpcProtocol is gRPC protocol type GrpcProtocol struct { protocol.BaseProtocol serverMap map[string]*Server serverLock sync.Mutex } -// NewGRPCProtocol ... +// NewGRPCProtocol creates new gRPC protocol func NewGRPCProtocol() *GrpcProtocol { return &GrpcProtocol{ BaseProtocol: protocol.NewBaseProtocol(), @@ -54,7 +54,7 @@ func NewGRPCProtocol() *GrpcProtocol { } } -// Export ... +// Export gRPC service for remote invocation func (gp *GrpcProtocol) Export(invoker protocol.Invoker) protocol.Exporter { url := invoker.GetUrl() serviceKey := url.ServiceKey() @@ -84,7 +84,7 @@ func (gp *GrpcProtocol) openServer(url common.URL) { } } -// Refer ... +// Refer a remote gRPC service func (gp *GrpcProtocol) Refer(url common.URL) protocol.Invoker { invoker := NewGrpcInvoker(url, NewClient(url)) gp.SetInvokers(invoker) @@ -92,7 +92,7 @@ func (gp *GrpcProtocol) Refer(url common.URL) protocol.Invoker { return invoker } -// Destroy ... +// Destroy will destroy gRPC all invoker and exporter, so it only is called once. func (gp *GrpcProtocol) Destroy() { logger.Infof("GrpcProtocol destroy.") @@ -104,7 +104,7 @@ func (gp *GrpcProtocol) Destroy() { } } -// GetProtocol ... +// GetProtocol gets gRPC protocol , will create if null. func GetProtocol() protocol.Protocol { if grpcProtocol == nil { grpcProtocol = NewGRPCProtocol() diff --git a/protocol/grpc/internal/server.go b/protocol/grpc/internal/server.go index a6b861cac6ccb73f8bdf894f462f380123fa9ae3..f7b99fa0ba557fa002321b5d2435d17cf792dd38 100644 --- a/protocol/grpc/internal/server.go +++ b/protocol/grpc/internal/server.go @@ -42,7 +42,7 @@ func (s *server) SayHello(ctx context.Context, in *HelloRequest) (*HelloReply, e return &HelloReply{Message: "Hello " + in.GetName()}, nil } -// InitGrpcServer ... +// InitGrpcServer creates global gRPC server. func InitGrpcServer() { port := ":30000" @@ -57,7 +57,7 @@ func InitGrpcServer() { } } -// ShutdownGrpcServer ... +// ShutdownGrpcServer shuts down gRPC server gracefully func ShutdownGrpcServer() { if s == nil { return diff --git a/protocol/grpc/protoc-gen-dubbo/plugin/dubbo/dubbo.go b/protocol/grpc/protoc-gen-dubbo/plugin/dubbo/dubbo.go index 83d28519f6f8e28bf471ce2ea6807603c1324911..1af4fafdc606783e937ede63f99e5a08f0b2419e 100644 --- a/protocol/grpc/protoc-gen-dubbo/plugin/dubbo/dubbo.go +++ b/protocol/grpc/protoc-gen-dubbo/plugin/dubbo/dubbo.go @@ -107,7 +107,6 @@ func (g *dubboGrpc) GenerateImports(file *generator.FileDescriptor) { g.P(`dgrpc "github.com/apache/dubbo-go/protocol/grpc"`) g.P(`"github.com/apache/dubbo-go/protocol/invocation"`) g.P(`"github.com/apache/dubbo-go/protocol"`) - g.P(`"github.com/apache/dubbo-go/config"`) g.P(` ) `) } @@ -266,7 +265,7 @@ func (g *dubboGrpc) generateServerMethod(servName, fullServName string, method * g.P(`invo := invocation.NewRPCInvocation("`, methName, `", args, nil)`) g.P("if interceptor == nil {") - g.P("result := base.GetProxyImpl().Invoke(invo)") + g.P("result := base.GetProxyImpl().Invoke(context.Background(), invo)") g.P("return result.Result(), result.Error()") g.P("}") @@ -276,7 +275,7 @@ func (g *dubboGrpc) generateServerMethod(servName, fullServName string, method * g.P("}") g.P("handler := func(ctx ", contextPkg, ".Context, req interface{}) (interface{}, error) {") - g.P("result := base.GetProxyImpl().Invoke(invo)") + g.P("result := base.GetProxyImpl().Invoke(context.Background(), invo)") g.P("return result.Result(), result.Error()") g.P("}") diff --git a/protocol/grpc/server.go b/protocol/grpc/server.go index 63783040f9840c26dbd0cc843e9d49cdc981e64a..4017b65dd5c35ef19795b390e40d7afff6699306 100644 --- a/protocol/grpc/server.go +++ b/protocol/grpc/server.go @@ -37,24 +37,27 @@ import ( "github.com/apache/dubbo-go/protocol" ) -// Server ... +// Server is a gRPC server type Server struct { grpcServer *grpc.Server } -// NewServer ... +// NewServer creates a new server func NewServer() *Server { return &Server{} } -// DubboGrpcService ... +// DubboGrpcService is gRPC service type DubboGrpcService interface { + // SetProxyImpl sets proxy. SetProxyImpl(impl protocol.Invoker) + // GetProxyImpl gets proxy. GetProxyImpl() protocol.Invoker + // ServiceDesc gets an RPC service's specification. ServiceDesc() *grpc.ServiceDesc } -// Start ... +// Start gRPC server with @url func (s *Server) Start(url common.URL) { var ( addr string @@ -106,7 +109,7 @@ func (s *Server) Start(url common.URL) { }() } -// Stop ... +// Stop gRPC server func (s *Server) Stop() { s.grpcServer.Stop() } diff --git a/protocol/invocation.go b/protocol/invocation.go index eedf5f0253c2b76a3e0e1b52a00124d648351cfc..ba5949794c0120874ebdf31cfb1fd9c7d8ac08e4 100644 --- a/protocol/invocation.go +++ b/protocol/invocation.go @@ -21,17 +21,26 @@ import ( "reflect" ) -// Invocation ... +// Invocation is a invocation for each remote method. type Invocation interface { + // MethodName gets invocation method name. MethodName() string + // ParameterTypes gets invocation parameter types. ParameterTypes() []reflect.Type + // ParameterValues gets invocation parameter values. ParameterValues() []reflect.Value + // Arguments gets arguments. Arguments() []interface{} + // Reply gets response of request Reply() interface{} + // Attachments gets all attachments Attachments() map[string]string + // AttachmentsByKey gets attachment by key , if nil then return default value AttachmentsByKey(string, string) string - // Refer to dubbo 2.7.6. It is different from attachment. It is used in internal process. + // Attributes refers to dubbo 2.7.6. It is different from attachment. It is used in internal process. Attributes() map[string]interface{} + // AttributeByKey gets attribute by key , if nil then return default value AttributeByKey(string, interface{}) interface{} + // Invoker gets the invoker in current context. Invoker() Invoker } diff --git a/protocol/invocation/rpcinvocation.go b/protocol/invocation/rpcinvocation.go index 68fe7b92042e6b4cf4a253c9ce354184f79af558..7f2cede9295e24c521de017ab3a1da7eaad250ab 100644 --- a/protocol/invocation/rpcinvocation.go +++ b/protocol/invocation/rpcinvocation.go @@ -31,7 +31,7 @@ import ( // /////////////////////////// // todo: is it necessary to separate fields of consumer(provider) from RPCInvocation -// RPCInvocation ... +// nolint type RPCInvocation struct { methodName string parameterTypes []reflect.Type @@ -46,7 +46,7 @@ type RPCInvocation struct { lock sync.RWMutex } -// NewRPCInvocation ... +// NewRPCInvocation creates a RPC invocation. func NewRPCInvocation(methodName string, arguments []interface{}, attachments map[string]string) *RPCInvocation { return &RPCInvocation{ methodName: methodName, @@ -56,7 +56,7 @@ func NewRPCInvocation(methodName string, arguments []interface{}, attachments ma } } -// NewRPCInvocationWithOptions ... +// NewRPCInvocationWithOptions creates a RPC invocation with @opts. func NewRPCInvocationWithOptions(opts ...option) *RPCInvocation { invo := &RPCInvocation{} for _, opt := range opts { @@ -68,42 +68,42 @@ func NewRPCInvocationWithOptions(opts ...option) *RPCInvocation { return invo } -// MethodName ... +// MethodName gets RPC invocation method name. func (r *RPCInvocation) MethodName() string { return r.methodName } -// ParameterTypes ... +// ParameterTypes gets RPC invocation parameter types. func (r *RPCInvocation) ParameterTypes() []reflect.Type { return r.parameterTypes } -// ParameterValues ... +// ParameterValues gets RPC invocation parameter values. func (r *RPCInvocation) ParameterValues() []reflect.Value { return r.parameterValues } -// Arguments ... +// Arguments gets RPC arguments. func (r *RPCInvocation) Arguments() []interface{} { return r.arguments } -// Reply ... +// Reply gets response of RPC request. func (r *RPCInvocation) Reply() interface{} { return r.reply } -// SetReply ... +// SetReply sets response of RPC request. func (r *RPCInvocation) SetReply(reply interface{}) { r.reply = reply } -// Attachments ... +// Attachments gets all attachments of RPC. func (r *RPCInvocation) Attachments() map[string]string { return r.attachments } -// AttachmentsByKey ... +// AttachmentsByKey gets RPC attachment by key , if nil then return default value. func (r *RPCInvocation) AttachmentsByKey(key string, defaultValue string) string { r.lock.RLock() defer r.lock.RUnlock() @@ -117,12 +117,12 @@ func (r *RPCInvocation) AttachmentsByKey(key string, defaultValue string) string return defaultValue } -// get attributes +// Attributes gets all attributes of RPC. func (r *RPCInvocation) Attributes() map[string]interface{} { return r.attributes } -// get attribute by key. If it is not exist, it will return default value +// AttributeByKey gets attribute by @key. If it is not exist, it will return default value. func (r *RPCInvocation) AttributeByKey(key string, defaultValue interface{}) interface{} { r.lock.RLock() defer r.lock.RUnlock() @@ -133,7 +133,7 @@ func (r *RPCInvocation) AttributeByKey(key string, defaultValue interface{}) int return defaultValue } -// SetAttachments ... +// SetAttachments sets attribute by @key and @value. func (r *RPCInvocation) SetAttachments(key string, value string) { r.lock.Lock() defer r.lock.Unlock() @@ -143,29 +143,24 @@ func (r *RPCInvocation) SetAttachments(key string, value string) { r.attachments[key] = value } -// SetAttribute. If Attributes is nil, it will be inited. +// SetAttribute sets attribute by @key and @value. func (r *RPCInvocation) SetAttribute(key string, value interface{}) { r.lock.Lock() defer r.lock.Unlock() r.attributes[key] = value } -// Invoker ... +// Invoker gets the invoker in current context. func (r *RPCInvocation) Invoker() protocol.Invoker { return r.invoker } -// SetInvoker ... -func (r *RPCInvocation) SetInvoker() protocol.Invoker { - return r.invoker -} - -// CallBack ... +// CallBack sets RPC callback method. func (r *RPCInvocation) CallBack() interface{} { return r.callBack } -// SetCallBack ... +// SetCallBack sets RPC callback method. func (r *RPCInvocation) SetCallBack(c interface{}) { r.callBack = c } @@ -176,56 +171,56 @@ func (r *RPCInvocation) SetCallBack(c interface{}) { type option func(invo *RPCInvocation) -// WithMethodName ... +// WithMethodName creates option with @methodName. func WithMethodName(methodName string) option { return func(invo *RPCInvocation) { invo.methodName = methodName } } -// WithParameterTypes ... +// WithParameterTypes creates option with @parameterTypes. func WithParameterTypes(parameterTypes []reflect.Type) option { return func(invo *RPCInvocation) { invo.parameterTypes = parameterTypes } } -// WithParameterValues ... +// WithParameterValues creates option with @parameterValues func WithParameterValues(parameterValues []reflect.Value) option { return func(invo *RPCInvocation) { invo.parameterValues = parameterValues } } -// WithArguments ... +// WithArguments creates option with @arguments function. func WithArguments(arguments []interface{}) option { return func(invo *RPCInvocation) { invo.arguments = arguments } } -// WithReply ... +// WithReply creates option with @reply function. func WithReply(reply interface{}) option { return func(invo *RPCInvocation) { invo.reply = reply } } -// WithCallBack ... +// WithCallBack creates option with @callback function. func WithCallBack(callBack interface{}) option { return func(invo *RPCInvocation) { invo.callBack = callBack } } -// WithAttachments ... +// WithAttachments creates option with @attachments. func WithAttachments(attachments map[string]string) option { return func(invo *RPCInvocation) { invo.attachments = attachments } } -// WithInvoker ... +// WithInvoker creates option with @invoker. func WithInvoker(invoker protocol.Invoker) option { return func(invo *RPCInvocation) { invo.invoker = invoker diff --git a/protocol/invoker.go b/protocol/invoker.go index bb71bab1cfa2ede7fb035912ae996f9adb7411e0..3ca370479cbe2255f26628b855b11b07396f1b6d 100644 --- a/protocol/invoker.go +++ b/protocol/invoker.go @@ -31,6 +31,7 @@ import ( // Extension - Invoker type Invoker interface { common.Node + // Invoke the invocation and return result. Invoke(context.Context, Invocation) Result } @@ -38,14 +39,14 @@ type Invoker interface { // base invoker ///////////////////////////// -// BaseInvoker ... +// BaseInvoker provides default invoker implement type BaseInvoker struct { url common.URL available bool destroyed bool } -// NewBaseInvoker ... +// NewBaseInvoker creates a new BaseInvoker func NewBaseInvoker(url common.URL) *BaseInvoker { return &BaseInvoker{ url: url, @@ -54,27 +55,27 @@ func NewBaseInvoker(url common.URL) *BaseInvoker { } } -// GetUrl ... +// GetUrl gets base invoker URL func (bi *BaseInvoker) GetUrl() common.URL { return bi.url } -// IsAvailable ... +// IsAvailable gets available flag func (bi *BaseInvoker) IsAvailable() bool { return bi.available } -// IsDestroyed ... +// IsDestroyed gets destroyed flag func (bi *BaseInvoker) IsDestroyed() bool { return bi.destroyed } -// Invoke ... +// Invoke provides default invoker implement func (bi *BaseInvoker) Invoke(context context.Context, invocation Invocation) Result { return &RPCResult{} } -// Destroy ... +// Destroy changes available and destroyed flag func (bi *BaseInvoker) Destroy() { logger.Infof("Destroy invoker: %s", bi.GetUrl().String()) bi.destroyed = true diff --git a/protocol/jsonrpc/http.go b/protocol/jsonrpc/http.go index 70b3abd24f9451b4fa81d02eb9390823e6714470..5fca66d99399b2974f858cbedb31d9615a303637 100644 --- a/protocol/jsonrpc/http.go +++ b/protocol/jsonrpc/http.go @@ -63,7 +63,7 @@ type Request struct { // HTTP Client // //////////////////////////////////////////// -// HTTPOptions ... +// HTTPOptions is a HTTP option include HandshakeTimeout and HTTPTimeout. type HTTPOptions struct { HandshakeTimeout time.Duration HTTPTimeout time.Duration @@ -74,13 +74,13 @@ var defaultHTTPOptions = HTTPOptions{ HTTPTimeout: 3 * time.Second, } -// HTTPClient ... +// HTTPClient is a HTTP client ,include ID and options. type HTTPClient struct { ID int64 options HTTPOptions } -// NewHTTPClient ... +// NewHTTPClient creates a new HTTP client with HTTPOptions. func NewHTTPClient(opt *HTTPOptions) *HTTPClient { if opt == nil { opt = &defaultHTTPOptions @@ -100,7 +100,7 @@ func NewHTTPClient(opt *HTTPOptions) *HTTPClient { } } -// NewRequest ... +// NewRequest creates a new HTTP request with @service ,@method and @arguments. func (c *HTTPClient) NewRequest(service common.URL, method string, args interface{}) *Request { return &Request{ @@ -114,7 +114,7 @@ func (c *HTTPClient) NewRequest(service common.URL, method string, args interfac } } -// Call ... +// Call makes a HTTP call with @ctx , @service ,@req and @rsp func (c *HTTPClient) Call(ctx context.Context, service common.URL, req *Request, rsp interface{}) error { // header httpHeader := http.Header{} diff --git a/protocol/jsonrpc/json.go b/protocol/jsonrpc/json.go index 3176e193816bf95882539374672eeed7f9cddc44..389ead9c1a530742c872a238d89b2df5ae3462ca 100644 --- a/protocol/jsonrpc/json.go +++ b/protocol/jsonrpc/json.go @@ -37,7 +37,7 @@ const ( VERSION = "2.0" ) -// CodecData ... +// CodecData is codec data for json RPC. type CodecData struct { ID int64 Method string @@ -64,6 +64,7 @@ type Error struct { Data interface{} `json:"data,omitempty"` } +// Error decodes response error for a string. func (e *Error) Error() string { buf, err := json.Marshal(e) if err != nil { @@ -114,6 +115,7 @@ func newJsonClientCodec() *jsonClientCodec { } } +// Write codec data as byte. func (c *jsonClientCodec) Write(d *CodecData) ([]byte, error) { // If return error: it will be returned as is for this call. // Allow param to be only Array, Slice, Map or Struct. @@ -170,6 +172,7 @@ func (c *jsonClientCodec) Write(d *CodecData) ([]byte, error) { return buf.Bytes(), nil } +// Read bytes as structured data func (c *jsonClientCodec) Read(streamBytes []byte, x interface{}) error { c.rsp.reset() @@ -223,6 +226,7 @@ func (r *serverRequest) reset() { } } +// UnmarshalJSON unmarshals JSON for server request. func (r *serverRequest) UnmarshalJSON(raw []byte) error { r.reset() @@ -281,7 +285,7 @@ type serverResponse struct { Error interface{} `json:"error,omitempty"` } -// ServerCodec ... +// ServerCodec is codec data for request server. type ServerCodec struct { req serverRequest } @@ -296,7 +300,7 @@ func newServerCodec() *ServerCodec { return &ServerCodec{} } -// ReadHeader ... +// ReadHeader reads header and unmarshal to server codec func (c *ServerCodec) ReadHeader(header map[string]string, body []byte) error { if header["HttpMethod"] != "POST" { return &Error{Code: -32601, Message: "Method not found"} @@ -328,7 +332,7 @@ func (c *ServerCodec) ReadHeader(header map[string]string, body []byte) error { return nil } -// ReadBody ... +// ReadBody reads @x as request body. func (c *ServerCodec) ReadBody(x interface{}) error { // If x!=nil and return error e: // - Write() will be called with e.Error() in r.Error @@ -339,7 +343,7 @@ func (c *ServerCodec) ReadBody(x interface{}) error { return nil } - // 鍦ㄨ繖閲屾妸璇锋眰鍙傛暟json 瀛楃涓茶浆鎹㈡垚浜嗙浉搴旂殑struct + // the request parameter JSON string is converted to the corresponding struct params := []byte(*c.req.Params) if err := json.Unmarshal(*c.req.Params, x); err != nil { // Note: if c.request.Params is nil it's not an error, it's an optional member. @@ -362,7 +366,7 @@ func (c *ServerCodec) ReadBody(x interface{}) error { return nil } -// NewError ... +// NewError creates a error with @code and @message func NewError(code int, message string) *Error { return &Error{Code: code, Message: message} } @@ -380,6 +384,7 @@ func newError(message string) *Error { } } +// Write responses as byte func (c *ServerCodec) Write(errMsg string, x interface{}) ([]byte, error) { // If return error: nothing happens. // In r.Error will be "" or .Error() of error returned by: diff --git a/protocol/jsonrpc/jsonrpc_exporter.go b/protocol/jsonrpc/jsonrpc_exporter.go index c61cf9adaebe9105a87ece1dcbae4dbe706cb3fc..6f75f6aeae9fb1a8d75ded5f558e0ddae84686a0 100644 --- a/protocol/jsonrpc/jsonrpc_exporter.go +++ b/protocol/jsonrpc/jsonrpc_exporter.go @@ -28,19 +28,19 @@ import ( "github.com/apache/dubbo-go/protocol" ) -// JsonrpcExporter ... +// JsonrpcExporter is JSON RPC exporter and extends from base invoker. type JsonrpcExporter struct { protocol.BaseExporter } -// NewJsonrpcExporter ... +// NewJsonrpcExporter creates JSON RPC exporter with @key, @invoker and @exporterMap func NewJsonrpcExporter(key string, invoker protocol.Invoker, exporterMap *sync.Map) *JsonrpcExporter { return &JsonrpcExporter{ BaseExporter: *protocol.NewBaseExporter(key, invoker, exporterMap), } } -// Unexport ... +// Unexport exported JSON RPC service. func (je *JsonrpcExporter) Unexport() { serviceId := je.GetInvoker().GetUrl().GetParam(constant.BEAN_NAME_KEY, "") interfaceName := je.GetInvoker().GetUrl().GetParam(constant.INTERFACE_KEY, "") diff --git a/protocol/jsonrpc/jsonrpc_invoker.go b/protocol/jsonrpc/jsonrpc_invoker.go index b6e194ce0e93e84c164eccf8574e5eb20430f6e8..d84b980216ade6e569e68af31fc90e1ea16b3056 100644 --- a/protocol/jsonrpc/jsonrpc_invoker.go +++ b/protocol/jsonrpc/jsonrpc_invoker.go @@ -29,13 +29,13 @@ import ( invocation_impl "github.com/apache/dubbo-go/protocol/invocation" ) -// JsonrpcInvoker ... +// JsonrpcInvoker is JSON RPC invoker type JsonrpcInvoker struct { protocol.BaseInvoker client *HTTPClient } -// NewJsonrpcInvoker ... +// NewJsonrpcInvoker creates JSON RPC invoker with @url and @client func NewJsonrpcInvoker(url common.URL, client *HTTPClient) *JsonrpcInvoker { return &JsonrpcInvoker{ BaseInvoker: *protocol.NewBaseInvoker(url), @@ -43,7 +43,7 @@ func NewJsonrpcInvoker(url common.URL, client *HTTPClient) *JsonrpcInvoker { } } -// Invoke ... +// Invoke the JSON RPC invocation and return result. func (ji *JsonrpcInvoker) Invoke(ctx context.Context, invocation protocol.Invocation) protocol.Result { var ( diff --git a/protocol/jsonrpc/jsonrpc_protocol.go b/protocol/jsonrpc/jsonrpc_protocol.go index 64f708652d8cb4bf2a6d53488c9fe17e64f10ad0..90a6bf5ef7aa017488f723804b22cc613850bcf2 100644 --- a/protocol/jsonrpc/jsonrpc_protocol.go +++ b/protocol/jsonrpc/jsonrpc_protocol.go @@ -44,14 +44,14 @@ func init() { var jsonrpcProtocol *JsonrpcProtocol -// JsonrpcProtocol ... +// JsonrpcProtocol is JSON RPC protocol. type JsonrpcProtocol struct { protocol.BaseProtocol serverMap map[string]*Server serverLock sync.Mutex } -// NewJsonrpcProtocol ... +// NewJsonrpcProtocol creates JSON RPC protocol func NewJsonrpcProtocol() *JsonrpcProtocol { return &JsonrpcProtocol{ BaseProtocol: protocol.NewBaseProtocol(), @@ -59,7 +59,7 @@ func NewJsonrpcProtocol() *JsonrpcProtocol { } } -// Export ... +// Export JSON RPC service for remote invocation func (jp *JsonrpcProtocol) Export(invoker protocol.Invoker) protocol.Exporter { url := invoker.GetUrl() serviceKey := strings.TrimPrefix(url.Path, "/") @@ -74,7 +74,7 @@ func (jp *JsonrpcProtocol) Export(invoker protocol.Invoker) protocol.Exporter { return exporter } -// Refer ... +// Refer a remote JSON PRC service from registry func (jp *JsonrpcProtocol) Refer(url common.URL) protocol.Invoker { //default requestTimeout var requestTimeout = config.GetConsumerConfig().RequestTimeout @@ -93,7 +93,7 @@ func (jp *JsonrpcProtocol) Refer(url common.URL) protocol.Invoker { return invoker } -// Destroy ... +// Destroy will destroy all invoker and exporter, so it only is called once. func (jp *JsonrpcProtocol) Destroy() { logger.Infof("jsonrpcProtocol destroy.") @@ -125,7 +125,7 @@ func (jp *JsonrpcProtocol) openServer(url common.URL) { } } -// GetProtocol ... +// GetProtocol gets JSON RPC protocol. func GetProtocol() protocol.Protocol { if jsonrpcProtocol == nil { jsonrpcProtocol = NewJsonrpcProtocol() diff --git a/protocol/jsonrpc/server.go b/protocol/jsonrpc/server.go index fcea66632e787083823c1d06ca6c1698c45d5b23..aa458a1614df29997b05ac4462200f9e9ffffc25 100644 --- a/protocol/jsonrpc/server.go +++ b/protocol/jsonrpc/server.go @@ -59,7 +59,7 @@ const ( PathPrefix = byte('/') ) -// Server ... +// Server is JSON RPC server wrapper type Server struct { done chan struct{} once sync.Once @@ -69,7 +69,7 @@ type Server struct { timeout time.Duration } -// NewServer ... +// NewServer creates new JSON RPC server. func NewServer() *Server { return &Server{ done: make(chan struct{}), @@ -228,7 +228,7 @@ func accept(listener net.Listener, fn func(net.Conn)) error { } } -// Start ... +// Start JSON RPC server then ready for accept request. func (s *Server) Start(url common.URL) { listener, err := net.Listen("tcp", url.Location) if err != nil { @@ -255,7 +255,7 @@ func (s *Server) Start(url common.URL) { }() } -// Stop ... +// Stop JSON RPC server, just can be call once. func (s *Server) Stop() { s.once.Do(func() { close(s.done) diff --git a/protocol/protocol.go b/protocol/protocol.go index a873469a8ba361c9dfc922b071ffbf256c6a8b98..6bed5ec4c2be82edda7a642eb342381c53387460 100644 --- a/protocol/protocol.go +++ b/protocol/protocol.go @@ -29,15 +29,20 @@ import ( // Protocol // Extension - protocol type Protocol interface { + // Export service for remote invocation Export(invoker Invoker) Exporter + // Refer a remote service Refer(url common.URL) Invoker + // Destroy will destroy all invoker and exporter, so it only is called once. Destroy() } // Exporter // wrapping invoker type Exporter interface { + // GetInvoker gets invoker. GetInvoker() Invoker + // Unexport exported service. Unexport() } @@ -45,45 +50,45 @@ type Exporter interface { // base protocol ///////////////////////////// -// BaseProtocol ... +// BaseProtocol is default protocol implement. type BaseProtocol struct { exporterMap *sync.Map invokers []Invoker } -// NewBaseProtocol ... +// NewBaseProtocol creates a new BaseProtocol func NewBaseProtocol() BaseProtocol { return BaseProtocol{ exporterMap: new(sync.Map), } } -// SetExporterMap ... +// SetExporterMap set @exporter with @key to local memory. func (bp *BaseProtocol) SetExporterMap(key string, exporter Exporter) { bp.exporterMap.Store(key, exporter) } -// ExporterMap ... +// ExporterMap gets exporter map. func (bp *BaseProtocol) ExporterMap() *sync.Map { return bp.exporterMap } -// SetInvokers ... +// SetInvokers sets invoker into local memory func (bp *BaseProtocol) SetInvokers(invoker Invoker) { bp.invokers = append(bp.invokers, invoker) } -// Invokers ... +// Invokers gets all invokers func (bp *BaseProtocol) Invokers() []Invoker { return bp.invokers } -// Export ... +// Export is default export implement. func (bp *BaseProtocol) Export(invoker Invoker) Exporter { return NewBaseExporter("base", invoker, bp.exporterMap) } -// Refer ... +// Refer is default refer implement. func (bp *BaseProtocol) Refer(url common.URL) Invoker { return NewBaseInvoker(url) } @@ -113,14 +118,14 @@ func (bp *BaseProtocol) Destroy() { // base exporter ///////////////////////////// -// BaseExporter ... +// BaseExporter is default exporter implement. type BaseExporter struct { key string invoker Invoker exporterMap *sync.Map } -// NewBaseExporter ... +// NewBaseExporter creates a new BaseExporter func NewBaseExporter(key string, invoker Invoker, exporterMap *sync.Map) *BaseExporter { return &BaseExporter{ key: key, @@ -129,13 +134,13 @@ func NewBaseExporter(key string, invoker Invoker, exporterMap *sync.Map) *BaseEx } } -// GetInvoker ... +// GetInvoker gets invoker func (de *BaseExporter) GetInvoker() Invoker { return de.invoker } -// Unexport ... +// Unexport exported service. func (de *BaseExporter) Unexport() { logger.Infof("Exporter unexport.") de.invoker.Destroy() diff --git a/protocol/protocolwrapper/mock_protocol_filter.go b/protocol/protocolwrapper/mock_protocol_filter.go index dedf8aa64b6ae1b7b4782350e2625b02171aac44..8763c20410915d4e81afd35691be7d9ed490f7a1 100644 --- a/protocol/protocolwrapper/mock_protocol_filter.go +++ b/protocol/protocolwrapper/mock_protocol_filter.go @@ -28,19 +28,22 @@ import ( type mockProtocolFilter struct{} -// NewMockProtocolFilter ... +// NewMockProtocolFilter creates a new mock protocol func NewMockProtocolFilter() protocol.Protocol { return &mockProtocolFilter{} } +// Export mock service for remote invocation func (pfw *mockProtocolFilter) Export(invoker protocol.Invoker) protocol.Exporter { return protocol.NewBaseExporter("key", invoker, &sync.Map{}) } +// Refer a mock remote service func (pfw *mockProtocolFilter) Refer(url common.URL) protocol.Invoker { return protocol.NewBaseInvoker(url) } +// Destroy will do nothing func (pfw *mockProtocolFilter) Destroy() { } diff --git a/protocol/protocolwrapper/protocol_filter_wrapper.go b/protocol/protocolwrapper/protocol_filter_wrapper.go index 70d2da0faed3bc9797eb23cec653bea05d445d91..cba1d5d5bce8c3de387381d17cc3f7965bf3adac 100644 --- a/protocol/protocolwrapper/protocol_filter_wrapper.go +++ b/protocol/protocolwrapper/protocol_filter_wrapper.go @@ -31,7 +31,7 @@ import ( ) const ( - // FILTER ... + // FILTER is protocol key. FILTER = "filter" ) @@ -45,7 +45,7 @@ type ProtocolFilterWrapper struct { protocol protocol.Protocol } -// Export ... +// Export service for remote invocation func (pfw *ProtocolFilterWrapper) Export(invoker protocol.Invoker) protocol.Exporter { if pfw.protocol == nil { pfw.protocol = extension.GetProtocol(invoker.GetUrl().Protocol) @@ -54,7 +54,7 @@ func (pfw *ProtocolFilterWrapper) Export(invoker protocol.Invoker) protocol.Expo return pfw.protocol.Export(invoker) } -// Refer ... +// Refer a remote service func (pfw *ProtocolFilterWrapper) Refer(url common.URL) protocol.Invoker { if pfw.protocol == nil { pfw.protocol = extension.GetProtocol(url.Protocol) @@ -62,7 +62,7 @@ func (pfw *ProtocolFilterWrapper) Refer(url common.URL) protocol.Invoker { return buildInvokerChain(pfw.protocol.Refer(url), constant.REFERENCE_FILTER_KEY) } -// Destroy ... +// Destroy will destroy all invoker and exporter. func (pfw *ProtocolFilterWrapper) Destroy() { pfw.protocol.Destroy() } diff --git a/protocol/result.go b/protocol/result.go index 34e76d2dddbaed33b2e2c015631443565cfaea87..2e7a6e492a60888ec9d9f420c77e6b77aee6aa70 100644 --- a/protocol/result.go +++ b/protocol/result.go @@ -17,15 +17,23 @@ package protocol -// Result ... +// Result is a RPC result type Result interface { + // SetError sets error. SetError(error) + // Error gets error. Error() error + // SetResult sets invoker result. SetResult(interface{}) + // Result gets invoker result. Result() interface{} + // SetAttachments replaces the existing attachments with the specified param. SetAttachments(map[string]string) + // Attachments gets all attachments Attachments() map[string]string + // AddAttachment adds the specified map to existing attachments in this instance. AddAttachment(string, string) + // Attachment gets attachment by key with default value. Attachment(string, string) string } @@ -33,48 +41,49 @@ type Result interface { // Result Impletment of RPC ///////////////////////////// -// RPCResult ... +// RPCResult is default RPC result. type RPCResult struct { Attrs map[string]string Err error Rest interface{} } -// SetError ... +// SetError sets error. func (r *RPCResult) SetError(err error) { r.Err = err } +// Error gets error. func (r *RPCResult) Error() error { return r.Err } -// SetResult ... +// SetResult sets invoker result. func (r *RPCResult) SetResult(rest interface{}) { r.Rest = rest } -// Result ... +// Result gets invoker result. func (r *RPCResult) Result() interface{} { return r.Rest } -// SetAttachments ... +// SetAttachments replaces the existing attachments with the specified param. func (r *RPCResult) SetAttachments(attr map[string]string) { r.Attrs = attr } -// Attachments ... +// Attachments gets all attachments func (r *RPCResult) Attachments() map[string]string { return r.Attrs } -// AddAttachment ... +// AddAttachment adds the specified map to existing attachments in this instance. func (r *RPCResult) AddAttachment(key, value string) { r.Attrs[key] = value } -// Attachment ... +// Attachment gets attachment by key with default value. func (r *RPCResult) Attachment(key, defaultValue string) string { v, ok := r.Attrs[key] if !ok { diff --git a/protocol/rpc_status.go b/protocol/rpc_status.go index 13be47c98ece1cc006250ad49ab2b9a8c3b1f625..0eeca6c1bba1f471117eb687a92d0458b9d5901d 100644 --- a/protocol/rpc_status.go +++ b/protocol/rpc_status.go @@ -32,7 +32,7 @@ var ( serviceStatistic sync.Map // url -> RPCStatus ) -// RPCStatus ... +// RPCStatus is URL statistics. type RPCStatus struct { active int32 failed int32 @@ -46,63 +46,63 @@ type RPCStatus struct { lastRequestFailedTimestamp int64 } -// GetActive ... +// GetActive gets active. func (rpc *RPCStatus) GetActive() int32 { return atomic.LoadInt32(&rpc.active) } -// GetFailed ... +// GetFailed gets failed. func (rpc *RPCStatus) GetFailed() int32 { return atomic.LoadInt32(&rpc.failed) } -// GetTotal ... +// GetTotal gets total. func (rpc *RPCStatus) GetTotal() int32 { return atomic.LoadInt32(&rpc.total) } -// GetTotalElapsed ... +// GetTotalElapsed gets total elapsed. func (rpc *RPCStatus) GetTotalElapsed() int64 { return atomic.LoadInt64(&rpc.totalElapsed) } -// GetFailedElapsed ... +// GetFailedElapsed gets failed elapsed. func (rpc *RPCStatus) GetFailedElapsed() int64 { return atomic.LoadInt64(&rpc.failedElapsed) } -// GetMaxElapsed ... +// GetMaxElapsed gets max elapsed. func (rpc *RPCStatus) GetMaxElapsed() int64 { return atomic.LoadInt64(&rpc.maxElapsed) } -// GetFailedMaxElapsed ... +// GetFailedMaxElapsed gets failed max elapsed. func (rpc *RPCStatus) GetFailedMaxElapsed() int64 { return atomic.LoadInt64(&rpc.failedMaxElapsed) } -// GetSucceededMaxElapsed ... +// GetSucceededMaxElapsed gets succeeded max elapsed. func (rpc *RPCStatus) GetSucceededMaxElapsed() int64 { return atomic.LoadInt64(&rpc.succeededMaxElapsed) } -// GetLastRequestFailedTimestamp ... +// GetLastRequestFailedTimestamp gets last request failed timestamp. func (rpc *RPCStatus) GetLastRequestFailedTimestamp() int64 { return atomic.LoadInt64(&rpc.lastRequestFailedTimestamp) } -// GetSuccessiveRequestFailureCount ... +// GetSuccessiveRequestFailureCount gets successive request failure count. func (rpc *RPCStatus) GetSuccessiveRequestFailureCount() int32 { return atomic.LoadInt32(&rpc.successiveRequestFailureCount) } -// GetURLStatus ... +// GetURLStatus get URL RPC status. func GetURLStatus(url common.URL) *RPCStatus { rpcStatus, _ := serviceStatistic.LoadOrStore(url.Key(), &RPCStatus{}) return rpcStatus.(*RPCStatus) } -// GetMethodStatus ... +// GetMethodStatus get method RPC status. func GetMethodStatus(url common.URL, methodName string) *RPCStatus { identifier := url.Key() methodMap, found := methodStatistics.Load(identifier) @@ -122,13 +122,13 @@ func GetMethodStatus(url common.URL, methodName string) *RPCStatus { return status } -// BeginCount ... +// BeginCount gets begin count. func BeginCount(url common.URL, methodName string) { beginCount0(GetURLStatus(url)) beginCount0(GetMethodStatus(url, methodName)) } -// EndCount ... +// EndCount gets end count. func EndCount(url common.URL, methodName string, elapsed int64, succeeded bool) { endCount0(GetURLStatus(url), elapsed, succeeded) endCount0(GetMethodStatus(url, methodName), elapsed, succeeded) @@ -163,7 +163,7 @@ func endCount0(rpcStatus *RPCStatus, elapsed int64, succeeded bool) { } } -// CurrentTimeMillis ... +// CurrentTimeMillis get current timestamp func CurrentTimeMillis() int64 { return time.Now().UnixNano() / int64(time.Millisecond) } diff --git a/registry/etcdv3/registry.go b/registry/etcdv3/registry.go index 0fbf98ae9e849bae6e170b70e23ab0eaa3f072f5..f3df78177bda2b068d0ad88156b593ab3d48c5d7 100644 --- a/registry/etcdv3/registry.go +++ b/registry/etcdv3/registry.go @@ -67,7 +67,7 @@ func (r *etcdV3Registry) SetClient(client *etcdv3.Client) { r.client = client } -// ClientLock gets registry control lock +// ClientLock returns lock for client func (r *etcdV3Registry) ClientLock() *sync.Mutex { return &r.cltLock } diff --git a/remoting/etcdv3/client.go b/remoting/etcdv3/client.go index ba3ea6e864923b1e70cc4a0d31ee98415807699c..b337c79584cc5058e89bd582b007e72fb10da7ee 100644 --- a/remoting/etcdv3/client.go +++ b/remoting/etcdv3/client.go @@ -45,13 +45,12 @@ const ( ) var ( - // ErrNilETCDV3Client ... + // Defines related errors ErrNilETCDV3Client = perrors.New("etcd raw client is nil") // full describe the ERR - // ErrKVPairNotFound ... - ErrKVPairNotFound = perrors.New("k/v pair not found") + ErrKVPairNotFound = perrors.New("k/v pair not found") ) -// Options ... +// nolint type Options struct { name string endpoints []string @@ -60,38 +59,38 @@ type Options struct { heartbeat int // heartbeat second } -// Option ... +// Option will define a function of handling Options type Option func(*Options) -// WithEndpoints ... +// WithEndpoints sets etcd client endpoints func WithEndpoints(endpoints ...string) Option { return func(opt *Options) { opt.endpoints = endpoints } } -// WithName ... +// WithName sets etcd client name func WithName(name string) Option { return func(opt *Options) { opt.name = name } } -// WithTimeout ... +// WithTimeout sets etcd client timeout func WithTimeout(timeout time.Duration) Option { return func(opt *Options) { opt.timeout = timeout } } -// WithHeartbeat ... +// WithHeartbeat sets etcd client heartbeat func WithHeartbeat(heartbeat int) Option { return func(opt *Options) { opt.heartbeat = heartbeat } } -// ValidateClient ... +// ValidateClient validates client and sets options func ValidateClient(container clientFacade, opts ...Option) error { options := &Options{ @@ -131,7 +130,7 @@ func ValidateClient(container clientFacade, opts ...Option) error { return nil } -// Client ... +// Client represents etcd client Configuration type Client struct { lock sync.RWMutex @@ -142,7 +141,7 @@ type Client struct { heartbeat int ctx context.Context // if etcd server connection lose, the ctx.Done will be sent msg - cancel context.CancelFunc // cancel the ctx, all watcher will stopped + cancel context.CancelFunc // cancel the ctx, all watcher will stopped rawClient *clientv3.Client exit chan struct{} @@ -206,7 +205,7 @@ func (c *Client) stop() bool { return false } -// Close ... +// nolint func (c *Client) Close() { if c == nil { @@ -265,8 +264,7 @@ func (c *Client) maintenanceStatusLoop(s *concurrency.Session) { } } -// if k not exist will put k/v in etcd -// if k is already exist in etcd, return nil +// if k not exist will put k/v in etcd, otherwise return nil func (c *Client) put(k string, v string, opts ...clientv3.OpOption) error { c.lock.RLock() @@ -325,7 +323,7 @@ func (c *Client) get(k string) (string, error) { return string(resp.Kvs[0].Value), nil } -// CleanKV ... +// nolint func (c *Client) CleanKV() error { c.lock.RLock() @@ -425,12 +423,12 @@ func (c *Client) keepAliveKV(k string, v string) error { return nil } -// Done ... +// nolint func (c *Client) Done() <-chan struct{} { return c.exit } -// Valid ... +// nolint func (c *Client) Valid() bool { select { case <-c.exit: @@ -447,7 +445,7 @@ func (c *Client) Valid() bool { return true } -// Create ... +// nolint func (c *Client) Create(k string, v string) error { err := c.put(k, v) @@ -457,7 +455,7 @@ func (c *Client) Create(k string, v string) error { return nil } -// Delete ... +// nolint func (c *Client) Delete(k string) error { err := c.delete(k) @@ -468,7 +466,7 @@ func (c *Client) Delete(k string) error { return nil } -// RegisterTemp ... +// RegisterTemp registers a temporary node func (c *Client) RegisterTemp(basePath string, node string) (string, error) { completeKey := path.Join(basePath, node) @@ -481,7 +479,7 @@ func (c *Client) RegisterTemp(basePath string, node string) (string, error) { return completeKey, nil } -// GetChildrenKVList ... +// GetChildrenKVList gets children kv list by @k func (c *Client) GetChildrenKVList(k string) ([]string, []string, error) { kList, vList, err := c.getChildren(k) @@ -491,7 +489,7 @@ func (c *Client) GetChildrenKVList(k string) ([]string, []string, error) { return kList, vList, nil } -// Get ... +// Get gets value by @k func (c *Client) Get(k string) (string, error) { v, err := c.get(k) @@ -502,7 +500,7 @@ func (c *Client) Get(k string) (string, error) { return v, nil } -// Watch ... +// Watch watches on spec key func (c *Client) Watch(k string) (clientv3.WatchChan, error) { wc, err := c.watch(k) @@ -512,7 +510,7 @@ func (c *Client) Watch(k string) (clientv3.WatchChan, error) { return wc, nil } -// WatchWithPrefix ... +// WatchWithPrefix watches on spec prefix func (c *Client) WatchWithPrefix(prefix string) (clientv3.WatchChan, error) { wc, err := c.watchWithPrefix(prefix) diff --git a/remoting/etcdv3/facade.go b/remoting/etcdv3/facade.go index 35befc85e449ec02a6377faec300aa6b46bcc8bf..3f5999fdf3c5a0791d780e8f5521ef3ea51e9372 100644 --- a/remoting/etcdv3/facade.go +++ b/remoting/etcdv3/facade.go @@ -43,7 +43,7 @@ type clientFacade interface { common.Node } -// HandleClientRestart ... +// HandleClientRestart keeps the connection between client and server func HandleClientRestart(r clientFacade) { var ( diff --git a/remoting/etcdv3/listener.go b/remoting/etcdv3/listener.go index e3cb74e4f676efa1f325ac45e32b21b39d1bbd6a..00b5b19b36d3baa8871efdd3d53e80f05d7aeac1 100644 --- a/remoting/etcdv3/listener.go +++ b/remoting/etcdv3/listener.go @@ -33,7 +33,7 @@ import ( "github.com/apache/dubbo-go/remoting" ) -// EventListener ... +// nolint type EventListener struct { client *Client keyMapLock sync.Mutex @@ -41,7 +41,7 @@ type EventListener struct { wg sync.WaitGroup } -// NewEventListener ... +// NewEventListener returns a EventListener instance func NewEventListener(client *Client) *EventListener { return &EventListener{ client: client, @@ -92,12 +92,10 @@ func (l *EventListener) ListenServiceNodeEvent(key string, listener ...remoting. } } } - - return false } -// return true mean the event type is DELETE -// return false mean the event type is CREATE || UPDATE +// return true means the event type is DELETE +// return false means the event type is CREATE || UPDATE func (l *EventListener) handleEvents(event *clientv3.Event, listeners ...remoting.DataListener) bool { logger.Infof("got a etcd event {type: %s, key: %s}", event.Type, event.Kv.Key) @@ -135,7 +133,7 @@ func (l *EventListener) handleEvents(event *clientv3.Event, listeners ...remotin panic("unreachable") } -// ListenServiceNodeEventWithPrefix Listen on a set of key with spec prefix +// ListenServiceNodeEventWithPrefix listens on a set of key with spec prefix func (l *EventListener) ListenServiceNodeEventWithPrefix(prefix string, listener ...remoting.DataListener) { defer l.wg.Done() for { @@ -151,12 +149,12 @@ func (l *EventListener) ListenServiceNodeEventWithPrefix(prefix string, listener logger.Warnf("etcd client stopped") return - // client ctx stop + // client ctx stop case <-l.client.ctx.Done(): logger.Warnf("etcd client ctx cancel") return - // etcd event stream + // etcd event stream case e, ok := <-wc: if !ok { @@ -230,7 +228,7 @@ func (l *EventListener) ListenServiceEvent(key string, listener remoting.DataLis }(key) } -// Close ... +// nolint func (l *EventListener) Close() { l.wg.Wait() } diff --git a/remoting/kubernetes/client.go b/remoting/kubernetes/client.go index 240257dbf55028a203bf9d419da0698fbfa9f8a3..0a0548959a3e6d839321d03a627bb6aba66d8474 100644 --- a/remoting/kubernetes/client.go +++ b/remoting/kubernetes/client.go @@ -46,8 +46,7 @@ type Client struct { controller *dubboRegistryController } -// newClient -// new a client for registry +// newClient returns Client instance for registry func newClient(url common.URL) (*Client, error) { ctx, cancel := context.WithCancel(context.Background()) @@ -75,8 +74,7 @@ func newClient(url common.URL) (*Client, error) { return c, nil } -// Create -// create k/v pair in watcher-set +// Create creates k/v pair in watcher-set func (c *Client) Create(k, v string) error { // the read current pod must be lock, protect every @@ -92,8 +90,7 @@ func (c *Client) Create(k, v string) error { return nil } -// GetChildren -// get k children list from kubernetes-watcherSet +// GetChildren gets k children list from kubernetes-watcherSet func (c *Client) GetChildren(k string) ([]string, []string, error) { objectList, err := c.controller.watcherSet.Get(k, true) @@ -112,8 +109,7 @@ func (c *Client) GetChildren(k string) ([]string, []string, error) { return kList, vList, nil } -// Watch -// watch on spec key +// Watch watches on spec key func (c *Client) Watch(k string) (<-chan *WatcherEvent, <-chan struct{}, error) { w, err := c.controller.watcherSet.Watch(k, false) @@ -124,8 +120,7 @@ func (c *Client) Watch(k string) (<-chan *WatcherEvent, <-chan struct{}, error) return w.ResultChan(), w.done(), nil } -// Watch -// watch on spec prefix +// WatchWithPrefix watches on spec prefix func (c *Client) WatchWithPrefix(prefix string) (<-chan *WatcherEvent, <-chan struct{}, error) { w, err := c.controller.watcherSet.Watch(prefix, true) @@ -136,9 +131,7 @@ func (c *Client) WatchWithPrefix(prefix string) (<-chan *WatcherEvent, <-chan st return w.ResultChan(), w.done(), nil } -// Valid -// Valid the client -// if return false, the client is die +// if returns false, the client is die func (c *Client) Valid() bool { select { @@ -151,14 +144,12 @@ func (c *Client) Valid() bool { return c.controller != nil } -// Done -// read the client status +// nolint func (c *Client) Done() <-chan struct{} { return c.ctx.Done() } -// Stop -// read the client status +// nolint func (c *Client) Close() { select { @@ -174,8 +165,7 @@ func (c *Client) Close() { // so, just wait } -// ValidateClient -// validate the kubernetes client +// ValidateClient validates the kubernetes client func ValidateClient(container clientFacade) error { client := container.Client() @@ -194,8 +184,7 @@ func ValidateClient(container clientFacade) error { return nil } -// NewMockClient -// export for registry package test +// NewMockClient exports for registry package test func NewMockClient(podList *v1.PodList) (*Client, error) { ctx, cancel := context.WithCancel(context.Background()) diff --git a/remoting/kubernetes/listener.go b/remoting/kubernetes/listener.go index a5e7a544fadfc249426d34ce68081ab3d4b01bdb..a737f4e0d4eae7d78bb17c47e9c216661c8b9c86 100644 --- a/remoting/kubernetes/listener.go +++ b/remoting/kubernetes/listener.go @@ -45,8 +45,8 @@ func NewEventListener(client *Client) *EventListener { } // Listen on a spec key -// this method will return true when spec key deleted, -// this method will return false when deep layer connection lose +// this method returns true when spec key deleted, +// this method returns false when deep layer connection lose func (l *EventListener) ListenServiceNodeEvent(key string, listener ...remoting.DataListener) bool { defer l.wg.Done() for { @@ -83,8 +83,8 @@ func (l *EventListener) ListenServiceNodeEvent(key string, listener ...remoting. } } -// return true mean the event type is DELETE -// return false mean the event type is CREATE || UPDATE +// return true means the event type is DELETE +// return false means the event type is CREATE || UPDATE func (l *EventListener) handleEvents(event *WatcherEvent, listeners ...remoting.DataListener) bool { logger.Infof("got a kubernetes-watcherSet event {type: %d, key: %s}", event.EventType, event.Key) diff --git a/remoting/kubernetes/registry_controller.go b/remoting/kubernetes/registry_controller.go index a9ca9e4d01ac19285d50a0b295b519538adf39cb..f93a00a6f2df6022d0436f56e8c719f108be66f3 100644 --- a/remoting/kubernetes/registry_controller.go +++ b/remoting/kubernetes/registry_controller.go @@ -72,8 +72,7 @@ var ( ErrDubboLabelAlreadyExist = perrors.New("dubbo label already exist") ) -// dubboRegistryController -// work like a kubernetes controller +// dubboRegistryController works like a kubernetes controller type dubboRegistryController struct { // clone from client @@ -364,8 +363,7 @@ func (c *dubboRegistryController) processNextWorkItem() bool { return true } -// handleWatchedPodEvent -// handle watched pod event +// handleWatchedPodEvent handles watched pod event func (c *dubboRegistryController) handleWatchedPodEvent(p *v1.Pod, eventType watch.EventType) { logger.Debugf("get @type = %s event from @pod = %s", eventType, p.GetName()) @@ -402,8 +400,7 @@ func (c *dubboRegistryController) handleWatchedPodEvent(p *v1.Pod, eventType wat } } -// unmarshalRecord -// unmarshal the kubernetes dubbo annotation value +// unmarshalRecord unmarshals the kubernetes dubbo annotation value func (c *dubboRegistryController) unmarshalRecord(record string) ([]*WatcherEvent, error) { if len(record) == 0 { @@ -453,8 +450,7 @@ func (c *dubboRegistryController) initCurrentPod() error { return nil } -// patch current pod -// write new meta for current pod +// patchCurrentPod writes new meta for current pod func (c *dubboRegistryController) patchCurrentPod(patch []byte) (*v1.Pod, error) { updatedPod, err := c.kc.CoreV1().Pods(c.namespace).Patch(c.name, types.StrategicMergePatchType, patch) if err != nil { @@ -463,7 +459,7 @@ func (c *dubboRegistryController) patchCurrentPod(patch []byte) (*v1.Pod, error) return updatedPod, nil } -// assemble the dubbo kubernetes label +// assembleDUBBOLabel assembles the dubbo kubernetes label // every dubbo instance should be labeled spec {"dubbo.io/label":"dubbo.io/label-value"} label func (c *dubboRegistryController) assembleDUBBOLabel(p *v1.Pod) (*v1.Pod, *v1.Pod, error) { var ( @@ -498,7 +494,7 @@ func (c *dubboRegistryController) assembleDUBBOLabel(p *v1.Pod) (*v1.Pod, *v1.Po return oldPod, newPod, nil } -// assemble the dubbo kubernetes annotations +// assembleDUBBOAnnotations assembles the dubbo kubernetes annotations // accord the current pod && (k,v) assemble the old-pod, new-pod func (c *dubboRegistryController) assembleDUBBOAnnotations(k, v string, currentPod *v1.Pod) (oldPod *v1.Pod, newPod *v1.Pod, err error) { @@ -528,8 +524,7 @@ func (c *dubboRegistryController) assembleDUBBOAnnotations(k, v string, currentP return } -// getPatch -// get the kubernetes pod patch bytes +// getPatch gets the kubernetes pod patch bytes func (c *dubboRegistryController) getPatch(oldPod, newPod *v1.Pod) ([]byte, error) { oldData, err := json.Marshal(oldPod) if err != nil { @@ -548,8 +543,7 @@ func (c *dubboRegistryController) getPatch(oldPod, newPod *v1.Pod) ([]byte, erro return patchBytes, nil } -// marshalRecord -// marshal the kubernetes dubbo annotation value +// marshalRecord marshals the kubernetes dubbo annotation value func (c *dubboRegistryController) marshalRecord(ol []*WatcherEvent) (string, error) { msg, err := json.Marshal(ol) if err != nil { @@ -558,7 +552,7 @@ func (c *dubboRegistryController) marshalRecord(ol []*WatcherEvent) (string, err return base64.URLEncoding.EncodeToString(msg), nil } -// read from kubernetes-env current pod status +// readCurrentPod reads from kubernetes-env current pod status func (c *dubboRegistryController) readCurrentPod() (*v1.Pod, error) { currentPod, err := c.kc.CoreV1().Pods(c.namespace).Get(c.name, metav1.GetOptions{}) if err != nil { @@ -567,7 +561,7 @@ func (c *dubboRegistryController) readCurrentPod() (*v1.Pod, error) { return currentPod, nil } -// add annotation for current pod +// addAnnotationForCurrentPod adds annotation for current pod func (c *dubboRegistryController) addAnnotationForCurrentPod(k string, v string) error { c.lock.Lock() diff --git a/remoting/kubernetes/watch.go b/remoting/kubernetes/watch.go index 3293ff1d923adb994ee9a7e9b9e79b6abb621195..07eeb09b4dd4627fdd3b18ee4d59356911b3a9b1 100644 --- a/remoting/kubernetes/watch.go +++ b/remoting/kubernetes/watch.go @@ -140,14 +140,12 @@ func (s *watcherSetImpl) Watch(key string, prefix bool) (Watcher, error) { return s.addWatcher(key, prefix) } -// Done -// get the watcher-set status +// Done gets the watcher-set status func (s *watcherSetImpl) Done() <-chan struct{} { return s.ctx.Done() } -// Put -// put the watch event to watcher-set +// Put puts the watch event to watcher-set func (s *watcherSetImpl) Put(watcherEvent *WatcherEvent) error { blockSendMsg := func(object *WatcherEvent, w *watcher) { @@ -243,8 +241,7 @@ func (s *watcherSetImpl) addWatcher(key string, prefix bool) (Watcher, error) { return w, nil } -// Get -// get elements from watcher-set +// Get gets elements from watcher-set func (s *watcherSetImpl) Get(key string, prefix bool) ([]*WatcherEvent, error) { s.lock.RLock() @@ -297,19 +294,17 @@ type watcher struct { exit chan struct{} } -// ResultChan +// nolint func (w *watcher) ResultChan() <-chan *WatcherEvent { return w.ch } -// ID -// the watcher's id +// nolint func (w *watcher) ID() string { return strconv.FormatUint(w.id, 10) } -// stop -// stop the watcher +// nolint func (w *watcher) stop() { // double close will panic @@ -318,14 +313,12 @@ func (w *watcher) stop() { }) } -// done -// check watcher status +// done checks watcher status func (w *watcher) done() <-chan struct{} { return w.exit } -// newWatcherSet -// new watcher set from parent context +// newWatcherSet returns new watcher set from parent context func newWatcherSet(ctx context.Context) WatcherSet { s := &watcherSetImpl{ ctx: ctx, diff --git a/remoting/listener.go b/remoting/listener.go index f7a3a2bd1662734919e093e1bd769223cd53447b..6cbb883181ff8ec1c9124f8d8cc3d7ec0920abd9 100644 --- a/remoting/listener.go +++ b/remoting/listener.go @@ -21,7 +21,7 @@ import ( "fmt" ) -// DataListener ... +// DataListener defines common data listener interface type DataListener interface { DataChange(eventType Event) bool //bool is return for interface implement is interesting } @@ -30,15 +30,15 @@ type DataListener interface { // event type ////////////////////////////////////////// -// SourceObjectEventType ... +// EventType means SourceObjectEventType type EventType int const ( - // EventTypeAdd ... + // EventTypeAdd means add event EventTypeAdd = iota - // EventTypeDel ... + // EventTypeDel means del event EventTypeDel - // EventTypeUpdate ... + // EventTypeUpdate means update event EventTypeUpdate ) @@ -56,7 +56,7 @@ func (t EventType) String() string { // service event ////////////////////////////////////////// -// Event ... +// Event defines common elements for service event type Event struct { Path string Action EventType diff --git a/remoting/zookeeper/client.go b/remoting/zookeeper/client.go index 92ea76046f002cbdf6dbe754453ef8ebb4a14de2..a8ad41846eaf933f0410bbb1ae44aef893c79d92 100644 --- a/remoting/zookeeper/client.go +++ b/remoting/zookeeper/client.go @@ -47,7 +47,7 @@ var ( errNilNode = perrors.Errorf("node does not exist") ) -// ZookeeperClient ... +// ZookeeperClient represents zookeeper client Configuration type ZookeeperClient struct { name string ZkAddrs []string @@ -59,7 +59,7 @@ type ZookeeperClient struct { eventRegistry map[string][]*chan struct{} } -// StateToString ... +// nolint func StateToString(state zk.State) string { switch state { case zk.StateDisconnected: @@ -89,7 +89,7 @@ func StateToString(state zk.State) string { } } -// Options ... +// nolint type Options struct { zkName string client *ZookeeperClient @@ -97,17 +97,17 @@ type Options struct { ts *zk.TestCluster } -// Option ... +// Option will define a function of handling Options type Option func(*Options) -// WithZkName ... +// WithZkName sets zk client name func WithZkName(name string) Option { return func(opt *Options) { opt.zkName = name } } -// ValidateZookeeperClient ... +// ValidateZookeeperClient validates client and sets options func ValidateZookeeperClient(container zkClientFacade, opts ...Option) error { var err error options := &Options{} @@ -187,14 +187,14 @@ func newZookeeperClient(name string, zkAddrs []string, timeout time.Duration) (* return z, nil } -// WithTestCluster ... +// WithTestCluster sets test cluser for zk client func WithTestCluster(ts *zk.TestCluster) Option { return func(opt *Options) { opt.ts = ts } } -// NewMockZookeeperClient ... +// NewMockZookeeperClient returns a mock client instance func NewMockZookeeperClient(name string, timeout time.Duration, opts ...Option) (*zk.TestCluster, *ZookeeperClient, <-chan zk.Event, error) { var ( err error @@ -226,21 +226,15 @@ func NewMockZookeeperClient(name string, timeout time.Duration, opts ...Option) } } - //callbackChan := make(chan zk.Event) - //f := func(event zk.Event) { - // callbackChan <- event - //} - z.Conn, event, err = ts.ConnectWithOptions(timeout) if err != nil { return nil, nil, nil, perrors.WithMessagef(err, "zk.Connect") } - //z.wait.Add(1) return ts, z, event, nil } -// HandleZkEvent ... +// HandleZkEvent handles zookeeper events func (z *ZookeeperClient) HandleZkEvent(session <-chan zk.Event) { var ( state int @@ -301,7 +295,7 @@ LOOP: } } -// RegisterEvent ... +// RegisterEvent registers zookeeper events func (z *ZookeeperClient) RegisterEvent(zkPath string, event *chan struct{}) { if zkPath == "" || event == nil { return @@ -316,7 +310,7 @@ func (z *ZookeeperClient) RegisterEvent(zkPath string, event *chan struct{}) { z.Unlock() } -// UnregisterEvent ... +// UnregisterEvent unregisters zookeeper events func (z *ZookeeperClient) UnregisterEvent(zkPath string, event *chan struct{}) { if zkPath == "" { return @@ -343,7 +337,7 @@ func (z *ZookeeperClient) UnregisterEvent(zkPath string, event *chan struct{}) { } } -// Done ... +// nolint func (z *ZookeeperClient) Done() <-chan struct{} { return z.exit } @@ -359,7 +353,7 @@ func (z *ZookeeperClient) stop() bool { return false } -// ZkConnValid ... +// ZkConnValid validates zookeeper connection func (z *ZookeeperClient) ZkConnValid() bool { select { case <-z.exit: @@ -377,7 +371,7 @@ func (z *ZookeeperClient) ZkConnValid() bool { return valid } -// Close ... +// nolint func (z *ZookeeperClient) Close() { if z == nil { return @@ -436,7 +430,7 @@ func (z *ZookeeperClient) CreateWithValue(basePath string, value []byte) error { return nil } -// Delete ... +// nolint func (z *ZookeeperClient) Delete(basePath string) error { var ( err error @@ -453,7 +447,7 @@ func (z *ZookeeperClient) Delete(basePath string) error { return perrors.WithMessagef(err, "Delete(basePath:%s)", basePath) } -// RegisterTemp ... +// RegisterTemp registers temporary node by @basePath and @node func (z *ZookeeperClient) RegisterTemp(basePath string, node string) (string, error) { var ( err error @@ -472,7 +466,6 @@ func (z *ZookeeperClient) RegisterTemp(basePath string, node string) (string, er tmpPath, err = conn.Create(zkPath, data, zk.FlagEphemeral, zk.WorldACL(zk.PermAll)) } - //if err != nil && err != zk.ErrNodeExists { if err != nil { logger.Warnf("conn.Create(\"%s\", zk.FlagEphemeral) = error(%v)\n", zkPath, perrors.WithStack(err)) return zkPath, perrors.WithStack(err) @@ -482,7 +475,7 @@ func (z *ZookeeperClient) RegisterTemp(basePath string, node string) (string, er return tmpPath, nil } -// RegisterTempSeq ... +// RegisterTempSeq register temporary sequence node by @basePath and @data func (z *ZookeeperClient) RegisterTempSeq(basePath string, data []byte) (string, error) { var ( err error @@ -513,7 +506,7 @@ func (z *ZookeeperClient) RegisterTempSeq(basePath string, data []byte) (string, return tmpPath, nil } -// GetChildrenW ... +// GetChildrenW gets children watch by @path func (z *ZookeeperClient) GetChildrenW(path string) ([]string, <-chan zk.Event, error) { var ( err error @@ -550,7 +543,7 @@ func (z *ZookeeperClient) GetChildrenW(path string) ([]string, <-chan zk.Event, return children, watcher.EvtCh, nil } -// GetChildren ... +// GetChildren gets children by @path func (z *ZookeeperClient) GetChildren(path string) ([]string, error) { var ( err error @@ -583,7 +576,7 @@ func (z *ZookeeperClient) GetChildren(path string) ([]string, error) { return children, nil } -// ExistW ... +// ExistW to judge watch whether it exists or not by @zkPath func (z *ZookeeperClient) ExistW(zkPath string) (<-chan zk.Event, error) { var ( exist bool @@ -611,7 +604,7 @@ func (z *ZookeeperClient) ExistW(zkPath string) (<-chan zk.Event, error) { return watcher.EvtCh, nil } -// GetContent ... +// GetContent gets content by @zkPath func (z *ZookeeperClient) GetContent(zkPath string) ([]byte, *zk.Stat, error) { return z.Conn.Get(zkPath) } diff --git a/remoting/zookeeper/facade.go b/remoting/zookeeper/facade.go index 4e3945388ff402f60a02150615a8914f9cba2435..10de42523e731d0780ff7132f4655850409135aa 100644 --- a/remoting/zookeeper/facade.go +++ b/remoting/zookeeper/facade.go @@ -40,7 +40,7 @@ type zkClientFacade interface { common.Node } -// HandleClientRestart ... +// HandleClientRestart keeps the connection between client and server func HandleClientRestart(r zkClientFacade) { var ( err error diff --git a/remoting/zookeeper/listener.go b/remoting/zookeeper/listener.go index b3f6e29bf81d4cddef058940e8942219427ac400..2c7f1f84d701d1f1b3994bf84402146de4200c06 100644 --- a/remoting/zookeeper/listener.go +++ b/remoting/zookeeper/listener.go @@ -37,7 +37,7 @@ import ( "github.com/apache/dubbo-go/remoting" ) -// ZkEventListener ... +// nolint type ZkEventListener struct { client *ZookeeperClient pathMapLock sync.Mutex @@ -45,7 +45,7 @@ type ZkEventListener struct { wg sync.WaitGroup } -// NewZkEventListener ... +// NewZkEventListener returns a EventListener instance func NewZkEventListener(client *ZookeeperClient) *ZkEventListener { return &ZkEventListener{ client: client, @@ -53,12 +53,12 @@ func NewZkEventListener(client *ZookeeperClient) *ZkEventListener { } } -// SetClient ... +// nolint func (l *ZkEventListener) SetClient(client *ZookeeperClient) { l.client = client } -// ListenServiceNodeEvent ... +// nolint func (l *ZkEventListener) ListenServiceNodeEvent(zkPath string, listener ...remoting.DataListener) bool { defer l.wg.Done() var zkEvent zk.Event @@ -312,7 +312,7 @@ func (l *ZkEventListener) valid() bool { return l.client.ZkConnValid() } -// Close ... +// nolint func (l *ZkEventListener) Close() { l.wg.Wait() }