You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@dubbo.apache.org by GitBox <gi...@apache.org> on 2020/12/25 12:51:41 UTC

[GitHub] [dubbo-go] AlexStocks commented on a change in pull request #959: Ftr: dubbogo 3.0 Triple support

AlexStocks commented on a change in pull request #959:
URL: https://github.com/apache/dubbo-go/pull/959#discussion_r548864629



##########
File path: go.mod
##########
@@ -5,21 +5,22 @@ require (
 	github.com/RoaringBitmap/roaring v0.5.5
 	github.com/Workiva/go-datastructures v1.0.52
 	github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5
-	github.com/alibaba/sentinel-golang v0.6.2
+	github.com/alibaba/sentinel-golang v0.6.1

Review comment:
       why u decrease sentinel-golang version?

##########
File path: protocol/dubbo3/dubbo3_exporter.go
##########
@@ -0,0 +1,52 @@
+/*
+ * 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 dubbo3
+
+import (
+	"sync"
+)
+
+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/protocol"
+)
+
+// DubboExporter is dubbo3 service exporter.
+type Dubbo3Exporter struct {
+	protocol.BaseExporter
+}
+
+// NewDubbo3Exporter get a Dubbo3Exporter.
+func NewDubbo3Exporter(key string, invoker protocol.Invoker, exporterMap *sync.Map) *Dubbo3Exporter {
+	return &Dubbo3Exporter{
+		BaseExporter: *protocol.NewBaseExporter(key, invoker, exporterMap),
+	}
+}
+
+// Unexport unexport dubbo3 service exporter.
+func (de *Dubbo3Exporter) Unexport() {
+	serviceId := de.GetInvoker().GetUrl().GetParam(constant.BEAN_NAME_KEY, "")
+	interfaceName := de.GetInvoker().GetUrl().GetParam(constant.INTERFACE_KEY, "")

Review comment:
       why not assign 'de.GetInvoker().GetUrl()' to a new var to decrease the invocation time?

##########
File path: protocol/dubbo3/dubbo3_invoker.go
##########
@@ -0,0 +1,142 @@
+/*
+ * 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 dubbo3
+
+import (
+	"context"
+	"reflect"
+	"strconv"
+	"strings"
+	"sync"
+	"time"
+)
+
+import (
+	hessian2 "github.com/apache/dubbo-go-hessian2"
+)
+
+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"
+	"github.com/apache/dubbo-go/protocol"
+	invocation_impl "github.com/apache/dubbo-go/protocol/invocation"
+	"github.com/apache/dubbo-go/remoting/dubbo3"
+)
+
+// Dubbo3Invoker is implement of protocol.Invoker. A dubboInvoker refer to one service and ip.
+type Dubbo3Invoker struct {
+	protocol.BaseInvoker
+	// the exchange layer, it is focus on network communication.
+	client   *dubbo3.TripleClient
+	quitOnce sync.Once
+	// timeout for service(interface) level.
+	timeout time.Duration
+	// Used to record the number of requests. -1 represent this DubboInvoker is destroyed
+	reqNum int64
+}
+
+// NewDubbo3Invoker constructor
+func NewDubbo3Invoker(url *common.URL) (*Dubbo3Invoker, error) {
+	requestTimeout := config.GetConsumerConfig().RequestTimeout
+	requestTimeoutStr := url.GetParam(constant.TIMEOUT_KEY, config.GetConsumerConfig().Request_Timeout)
+	if t, err := time.ParseDuration(requestTimeoutStr); err == nil {
+		requestTimeout = t
+	}
+
+	client, err := dubbo3.NewTripleClient(url)
+	if err != nil {
+		return nil, err
+	}
+
+	return &Dubbo3Invoker{
+		BaseInvoker: *protocol.NewBaseInvoker(url),
+		client:      client,
+		reqNum:      0,
+		timeout:     requestTimeout,
+	}, nil
+}
+
+// Invoke call remoting.
+func (di *Dubbo3Invoker) Invoke(ctx context.Context, invocation protocol.Invocation) protocol.Result {
+	var (
+		result protocol.RPCResult
+	)
+
+	var in []reflect.Value
+	in = append(in, reflect.ValueOf(ctx))
+	if len(invocation.ParameterValues()) > 0 {
+		in = append(in, invocation.ParameterValues()...)
+	}
+
+	methodName := invocation.MethodName()
+	method := di.client.Invoker.MethodByName(methodName)
+	res := method.Call(in)
+
+	result.Rest = res[0]
+	// check err
+	if !res[1].IsNil() {
+		result.Err = res[1].Interface().(error)
+	} else {
+		_ = hessian2.ReflectResponse(res[0], invocation.Reply())
+	}
+
+	return &result
+}
+
+// get timeout including methodConfig
+func (di *Dubbo3Invoker) getTimeout(invocation *invocation_impl.RPCInvocation) time.Duration {
+	var timeout = di.GetUrl().GetParam(strings.Join([]string{constant.METHOD_KEYS, invocation.MethodName(), constant.TIMEOUT_KEY}, "."), "")

Review comment:
       delete the var and using `:=` instead.

##########
File path: protocol/dubbo3/impl/header.go
##########
@@ -0,0 +1,145 @@
+/*
+ * 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 impl
+
+import (
+	"context"
+)
+
+import (
+	"golang.org/x/net/http2"
+	"golang.org/x/net/http2/hpack"
+)
+
+import (
+	"github.com/apache/dubbo-go/common"
+	"github.com/apache/dubbo-go/remoting"
+)
+
+func init() {
+	remoting.SetProtocolHeaderHandler("dubbo3", NewTripleHeaderHandler)
+}
+
+// TripleHeader define the h2 header of triple impl
+type TripleHeader struct {
+	method         string
+	streamID       uint32

Review comment:
       lower  case? why?

##########
File path: protocol/dubbo3/dubbo3_protocol.go
##########
@@ -0,0 +1,163 @@
+/*
+ * 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 dubbo3
+
+import (
+	"fmt"
+	"google.golang.org/grpc"
+	"reflect"
+	"sync"
+)
+
+import (
+	"github.com/apache/dubbo-go/common"
+	"github.com/apache/dubbo-go/common/constant"
+	"github.com/apache/dubbo-go/common/extension"
+	"github.com/apache/dubbo-go/common/logger"
+	"github.com/apache/dubbo-go/config"
+	"github.com/apache/dubbo-go/protocol"
+	"github.com/apache/dubbo-go/remoting/dubbo3"
+)
+
+const (
+	// DUBBO3 is dubbo3 protocol name
+	DUBBO3 = "dubbo3"
+)
+
+func init() {
+	logger.Warn("Init extension")
+	extension.SetProtocol(DUBBO3, GetProtocol)
+}
+
+var (
+	dubbo3Protocol *Dubbo3Protocol
+)
+
+// It support dubbo protocol. It implements Protocol interface for dubbo protocol.
+type Dubbo3Protocol struct {
+	protocol.BaseProtocol
+	// It is store relationship about serviceKey(group/interface:version) and ExchangeServer
+	// The ExchangeServer is introduced to replace of Server. Because Server is depend on getty directly.
+	serverMap  map[string]*dubbo3.TripleServer
+	serverLock sync.Mutex
+}
+
+// NewDubbo3Protocol create a dubbo protocol.
+func NewDubbo3Protocol() *Dubbo3Protocol {
+	return &Dubbo3Protocol{
+		BaseProtocol: protocol.NewBaseProtocol(),
+		serverMap:    make(map[string]*dubbo3.TripleServer),
+	}
+}
+
+// Export export dubbo3 service.
+func (dp *Dubbo3Protocol) Export(invoker protocol.Invoker) protocol.Exporter {
+	url := invoker.GetUrl()
+	serviceKey := url.ServiceKey()
+	exporter := NewDubbo3Exporter(serviceKey, invoker, dp.ExporterMap())
+	dp.SetExporterMap(serviceKey, exporter)
+	logger.Infof("Export service: %s", url.String())
+	// start server
+
+	dp.openServer(url)
+	return exporter
+}
+
+// Refer create dubbo3 service reference.
+func (dp *Dubbo3Protocol) Refer(url *common.URL) protocol.Invoker {
+	invoker, err := NewDubbo3Invoker(url)
+	if err != nil {
+		logger.Errorf("Refer url = %+v, with error = %s", *url, err.Error())
+		return nil
+	}
+	dp.SetInvokers(invoker)
+	logger.Infof("Refer service: %s", url.String())
+	return invoker
+}
+
+// Destroy destroy dubbo3 service.
+func (dp *Dubbo3Protocol) Destroy() {
+	dp.BaseProtocol.Destroy()
+
+	// stop server
+	for key, server := range dp.serverMap {
+		delete(dp.serverMap, key)
+		server.Stop()
+	}
+}
+
+// Dubbo3GrpcService is gRPC service
+type Dubbo3GrpcService interface {
+	// SetProxyImpl sets proxy.
+	SetProxyImpl(impl protocol.Invoker)
+	// GetProxyImpl gets proxy.
+	GetProxyImpl() protocol.Invoker
+	// ServiceDesc gets an RPC service's specification.
+	ServiceDesc() *grpc.ServiceDesc
+}
+
+// openServer open a dubbo3 server
+func (dp *Dubbo3Protocol) openServer(url *common.URL) {
+	_, ok := dp.serverMap[url.Location]
+	if !ok {

Review comment:
       pls do not write js-style if.

##########
File path: protocol/dubbo3/dubbo3_protocol.go
##########
@@ -0,0 +1,163 @@
+/*
+ * 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 dubbo3
+
+import (
+	"fmt"
+	"google.golang.org/grpc"
+	"reflect"
+	"sync"
+)
+
+import (
+	"github.com/apache/dubbo-go/common"
+	"github.com/apache/dubbo-go/common/constant"
+	"github.com/apache/dubbo-go/common/extension"
+	"github.com/apache/dubbo-go/common/logger"
+	"github.com/apache/dubbo-go/config"
+	"github.com/apache/dubbo-go/protocol"
+	"github.com/apache/dubbo-go/remoting/dubbo3"
+)
+
+const (
+	// DUBBO3 is dubbo3 protocol name
+	DUBBO3 = "dubbo3"
+)
+
+func init() {
+	logger.Warn("Init extension")
+	extension.SetProtocol(DUBBO3, GetProtocol)
+}
+
+var (
+	dubbo3Protocol *Dubbo3Protocol
+)
+
+// It support dubbo protocol. It implements Protocol interface for dubbo protocol.
+type Dubbo3Protocol struct {
+	protocol.BaseProtocol
+	// It is store relationship about serviceKey(group/interface:version) and ExchangeServer
+	// The ExchangeServer is introduced to replace of Server. Because Server is depend on getty directly.
+	serverMap  map[string]*dubbo3.TripleServer
+	serverLock sync.Mutex

Review comment:
       pls move the lock and place it above its guard object.

##########
File path: protocol/dubbo3/dubbo3_protocol.go
##########
@@ -0,0 +1,163 @@
+/*
+ * 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 dubbo3
+
+import (
+	"fmt"
+	"google.golang.org/grpc"
+	"reflect"
+	"sync"
+)
+
+import (
+	"github.com/apache/dubbo-go/common"
+	"github.com/apache/dubbo-go/common/constant"
+	"github.com/apache/dubbo-go/common/extension"
+	"github.com/apache/dubbo-go/common/logger"
+	"github.com/apache/dubbo-go/config"
+	"github.com/apache/dubbo-go/protocol"
+	"github.com/apache/dubbo-go/remoting/dubbo3"
+)
+
+const (
+	// DUBBO3 is dubbo3 protocol name
+	DUBBO3 = "dubbo3"
+)
+
+func init() {
+	logger.Warn("Init extension")

Review comment:
       write log in init?

##########
File path: protocol/dubbo3/dubbo3_invoker.go
##########
@@ -0,0 +1,142 @@
+/*
+ * 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 dubbo3
+
+import (
+	"context"
+	"reflect"
+	"strconv"
+	"strings"
+	"sync"
+	"time"
+)
+
+import (
+	hessian2 "github.com/apache/dubbo-go-hessian2"
+)
+
+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"
+	"github.com/apache/dubbo-go/protocol"
+	invocation_impl "github.com/apache/dubbo-go/protocol/invocation"
+	"github.com/apache/dubbo-go/remoting/dubbo3"
+)
+
+// Dubbo3Invoker is implement of protocol.Invoker. A dubboInvoker refer to one service and ip.
+type Dubbo3Invoker struct {
+	protocol.BaseInvoker
+	// the exchange layer, it is focus on network communication.
+	client   *dubbo3.TripleClient
+	quitOnce sync.Once
+	// timeout for service(interface) level.
+	timeout time.Duration
+	// Used to record the number of requests. -1 represent this DubboInvoker is destroyed
+	reqNum int64
+}
+
+// NewDubbo3Invoker constructor
+func NewDubbo3Invoker(url *common.URL) (*Dubbo3Invoker, error) {
+	requestTimeout := config.GetConsumerConfig().RequestTimeout
+	requestTimeoutStr := url.GetParam(constant.TIMEOUT_KEY, config.GetConsumerConfig().Request_Timeout)
+	if t, err := time.ParseDuration(requestTimeoutStr); err == nil {
+		requestTimeout = t
+	}
+
+	client, err := dubbo3.NewTripleClient(url)
+	if err != nil {
+		return nil, err
+	}
+
+	return &Dubbo3Invoker{
+		BaseInvoker: *protocol.NewBaseInvoker(url),
+		client:      client,
+		reqNum:      0,
+		timeout:     requestTimeout,
+	}, nil
+}
+
+// Invoke call remoting.
+func (di *Dubbo3Invoker) Invoke(ctx context.Context, invocation protocol.Invocation) protocol.Result {
+	var (
+		result protocol.RPCResult
+	)
+
+	var in []reflect.Value
+	in = append(in, reflect.ValueOf(ctx))

Review comment:
       using 'in := append(in, reflect.ValueOf(ctx))' instead

##########
File path: protocol/dubbo3/dubbo3_protocol.go
##########
@@ -0,0 +1,163 @@
+/*
+ * 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 dubbo3
+
+import (
+	"fmt"
+	"google.golang.org/grpc"

Review comment:
       move it to the second import block.

##########
File path: protocol/dubbo3/dubbo3_protocol.go
##########
@@ -0,0 +1,163 @@
+/*
+ * 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 dubbo3
+
+import (
+	"fmt"
+	"google.golang.org/grpc"
+	"reflect"
+	"sync"
+)
+
+import (
+	"github.com/apache/dubbo-go/common"
+	"github.com/apache/dubbo-go/common/constant"
+	"github.com/apache/dubbo-go/common/extension"
+	"github.com/apache/dubbo-go/common/logger"
+	"github.com/apache/dubbo-go/config"
+	"github.com/apache/dubbo-go/protocol"
+	"github.com/apache/dubbo-go/remoting/dubbo3"
+)
+
+const (
+	// DUBBO3 is dubbo3 protocol name
+	DUBBO3 = "dubbo3"
+)
+
+func init() {
+	logger.Warn("Init extension")
+	extension.SetProtocol(DUBBO3, GetProtocol)
+}
+
+var (
+	dubbo3Protocol *Dubbo3Protocol
+)
+
+// It support dubbo protocol. It implements Protocol interface for dubbo protocol.
+type Dubbo3Protocol struct {
+	protocol.BaseProtocol
+	// It is store relationship about serviceKey(group/interface:version) and ExchangeServer
+	// The ExchangeServer is introduced to replace of Server. Because Server is depend on getty directly.
+	serverMap  map[string]*dubbo3.TripleServer
+	serverLock sync.Mutex
+}
+
+// NewDubbo3Protocol create a dubbo protocol.
+func NewDubbo3Protocol() *Dubbo3Protocol {
+	return &Dubbo3Protocol{
+		BaseProtocol: protocol.NewBaseProtocol(),
+		serverMap:    make(map[string]*dubbo3.TripleServer),
+	}
+}
+
+// Export export dubbo3 service.
+func (dp *Dubbo3Protocol) Export(invoker protocol.Invoker) protocol.Exporter {
+	url := invoker.GetUrl()
+	serviceKey := url.ServiceKey()
+	exporter := NewDubbo3Exporter(serviceKey, invoker, dp.ExporterMap())
+	dp.SetExporterMap(serviceKey, exporter)
+	logger.Infof("Export service: %s", url.String())
+	// start server
+
+	dp.openServer(url)
+	return exporter
+}
+
+// Refer create dubbo3 service reference.
+func (dp *Dubbo3Protocol) Refer(url *common.URL) protocol.Invoker {
+	invoker, err := NewDubbo3Invoker(url)
+	if err != nil {
+		logger.Errorf("Refer url = %+v, with error = %s", *url, err.Error())
+		return nil
+	}
+	dp.SetInvokers(invoker)
+	logger.Infof("Refer service: %s", url.String())
+	return invoker
+}
+
+// Destroy destroy dubbo3 service.
+func (dp *Dubbo3Protocol) Destroy() {
+	dp.BaseProtocol.Destroy()
+
+	// stop server
+	for key, server := range dp.serverMap {
+		delete(dp.serverMap, key)
+		server.Stop()
+	}
+}
+
+// Dubbo3GrpcService is gRPC service
+type Dubbo3GrpcService interface {
+	// SetProxyImpl sets proxy.
+	SetProxyImpl(impl protocol.Invoker)
+	// GetProxyImpl gets proxy.
+	GetProxyImpl() protocol.Invoker
+	// ServiceDesc gets an RPC service's specification.
+	ServiceDesc() *grpc.ServiceDesc
+}
+
+// openServer open a dubbo3 server
+func (dp *Dubbo3Protocol) openServer(url *common.URL) {
+	_, ok := dp.serverMap[url.Location]
+	if !ok {
+		_, ok := dp.ExporterMap().Load(url.ServiceKey())
+		if !ok {
+			panic("[DubboProtocol]" + url.Key() + "is not existing")
+		}
+
+		dp.serverLock.Lock()
+		_, ok = dp.serverMap[url.Location]
+		if !ok {
+			key := url.GetParam(constant.BEAN_NAME_KEY, "")
+			service := config.GetProviderService(key)
+
+			m, ok := reflect.TypeOf(service).MethodByName("SetProxyImpl")
+			if !ok {
+				panic("method SetProxyImpl is necessary for grpc service")
+			}
+
+			exporter, _ := dubbo3Protocol.ExporterMap().Load(url.ServiceKey())
+			if exporter == nil {
+				panic(fmt.Sprintf("no exporter found for servicekey: %v", url.ServiceKey()))
+			}
+			invoker := exporter.(protocol.Exporter).GetInvoker()
+			if invoker == nil {
+				panic(fmt.Sprintf("no invoker found for servicekey: %v", url.ServiceKey()))
+			}
+
+			in := []reflect.Value{reflect.ValueOf(service)}
+			in = append(in, reflect.ValueOf(invoker))
+			m.Func.Call(in)
+
+			srv := dubbo3.NewTripleServer(url, service)
+
+			dp.serverMap[url.Location] = srv
+
+			srv.Start()
+		}
+		dp.serverLock.Unlock()

Review comment:
       using defer unlock, pls.

##########
File path: protocol/dubbo3/impl/package.go
##########
@@ -0,0 +1,54 @@
+/*
+ * 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 impl
+
+import (
+	"encoding/binary"
+)
+
+import (
+	"github.com/apache/dubbo-go/remoting"
+)
+
+// TriplePackageHandler handles package of triple
+// e.g. now it impl as deal with pkg data as: [:5]is length and [5:lenght] is body
+type TriplePackageHandler struct {
+	header *TripleHeader
+	//codec  *CodeC
+}
+
+func (t *TriplePackageHandler) Frame2PkgData(frameData []byte) []byte {
+	lineHeader := frameData[:5]
+	length := binary.BigEndian.Uint32(lineHeader[1:])
+	return frameData[5 : 5+length]
+}
+func (t *TriplePackageHandler) Pkg2FrameData(pkgData []byte) []byte {
+	rsp := make([]byte, 5+len(pkgData))
+	rsp[0] = byte(0)
+	binary.BigEndian.PutUint32(rsp[1:], uint32(len(pkgData)))
+	copy(rsp[5:], pkgData[:])
+	return rsp
+}
+
+func init() {

Review comment:
       pls move the init to the header of this file.

##########
File path: remoting/dubbo3/constant.go
##########
@@ -0,0 +1,21 @@
+/*
+ * 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 dubbo3
+
+const defaultRWBufferMaxLen = 4096

Review comment:
       firstly, u should place the tow constants into one const () block.
   
   sencondly, pls set the constant type of defaultRWBufferMaxLen.

##########
File path: protocol/dubbo3/impl/package.go
##########
@@ -0,0 +1,54 @@
+/*
+ * 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 impl
+
+import (
+	"encoding/binary"
+)
+
+import (
+	"github.com/apache/dubbo-go/remoting"
+)
+
+// TriplePackageHandler handles package of triple
+// e.g. now it impl as deal with pkg data as: [:5]is length and [5:lenght] is body
+type TriplePackageHandler struct {
+	header *TripleHeader
+	//codec  *CodeC
+}
+
+func (t *TriplePackageHandler) Frame2PkgData(frameData []byte) []byte {
+	lineHeader := frameData[:5]

Review comment:
       pls check the length of @frameData firstly.

##########
File path: remoting/dubbo3/dubbo3_client.go
##########
@@ -0,0 +1,140 @@
+/*
+ * 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 dubbo3
+
+import (
+	"context"
+	"net"
+	"reflect"
+)
+
+import (
+	"github.com/golang/protobuf/proto"
+	"google.golang.org/grpc"
+)
+
+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"
+)
+
+// TripleClient client endpoint for client end
+type TripleClient struct {
+	conn         net.Conn
+	h2Controller *H2Controller
+	addr         string
+	Invoker      reflect.Value
+	url          *common.URL
+}
+
+// TripleConn is the sturuct that called in pb.go file, it's client field contains all net logic of dubbo3
+type TripleConn struct {
+	client *TripleClient
+}
+
+// Invoke called when unary rpc 's pb.go file
+func (t *TripleConn) Invoke(ctx context.Context, method string, args, reply interface{}, opts ...grpc.CallOption) error {
+	t.client.Request(ctx, method, args, reply)
+	return nil
+}
+
+// NewStream called when streaming rpc 's pb.go file
+func (t *TripleConn) NewStream(ctx context.Context, method string, opts ...grpc.CallOption) (grpc.ClientStream, error) {
+	return t.client.StreamRequest(ctx, method)
+}
+
+// newTripleConn new a triple conn with given @tripleclient, which contains all net logic
+func newTripleConn(client *TripleClient) *TripleConn {
+	return &TripleConn{
+		client: client,
+	}
+}
+
+// getInvoker return invoker that have service method
+func getInvoker(impl interface{}, conn *TripleConn) interface{} {
+	var in []reflect.Value
+	in = append(in, reflect.ValueOf(conn))

Review comment:
       using :=

##########
File path: remoting/dubbo3/sstream.go
##########
@@ -0,0 +1,106 @@
+/*
+ * 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 dubbo3
+
+import (

Review comment:
       split it pls.

##########
File path: protocol/dubbo3/impl/header.go
##########
@@ -0,0 +1,145 @@
+/*
+ * 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 impl
+
+import (
+	"context"
+)
+
+import (
+	"golang.org/x/net/http2"
+	"golang.org/x/net/http2/hpack"
+)
+
+import (
+	"github.com/apache/dubbo-go/common"
+	"github.com/apache/dubbo-go/remoting"
+)
+
+func init() {
+	remoting.SetProtocolHeaderHandler("dubbo3", NewTripleHeaderHandler)
+}
+
+// TripleHeader define the h2 header of triple impl
+type TripleHeader struct {
+	method         string
+	streamID       uint32
+	ContentType    string
+	ServiceVersion string
+	ServiceGroup   string
+	RPCID          string
+	TracingID      string
+	TracingRPCID   string
+	TracingContext string
+	ClusterInfo    string
+}
+
+func (t *TripleHeader) GetMethod() string {
+	return t.method
+}
+func (t *TripleHeader) GetStreamID() uint32 {
+	return t.streamID
+}
+
+// FieldToCtx parse triple Header that user defined, to ctx of server end
+func (t *TripleHeader) FieldToCtx() context.Context {
+	ctx := context.WithValue(context.Background(), "tri-service-version", t.ServiceVersion)
+	ctx = context.WithValue(ctx, "tri-service-group", t.ServiceGroup)
+	ctx = context.WithValue(ctx, "tri-req-id", t.RPCID)
+	ctx = context.WithValue(ctx, "tri-trace-traceid", t.TracingID)
+	ctx = context.WithValue(ctx, "tri-trace-rpcid", t.TracingRPCID)
+	ctx = context.WithValue(ctx, "tri-trace-proto-bin", t.TracingContext)
+	ctx = context.WithValue(ctx, "tri-unit-info", t.ClusterInfo)
+	return ctx
+}
+
+func NewTripleHeaderHandler() remoting.ProtocolHeaderHandler {
+	return &TripleHeaderHandler{}
+}
+
+// TripleHeaderHandler Handler the change of triple header field and h2 field
+type TripleHeaderHandler struct {
+}
+
+// WriteHeaderField called when comsumer call server invoke,
+// it parse field of url and ctx to HTTP2 Header field, developer must assure "tri-" prefix field be string
+// if not, it will cause panic!
+func (t TripleHeaderHandler) WriteHeaderField(url *common.URL, ctx context.Context) []hpack.HeaderField {
+	headerFields := make([]hpack.HeaderField, 0, 2) // at least :status, content-type will be there if none else.
+	headerFields = append(headerFields, hpack.HeaderField{Name: ":method", Value: "POST"})
+	headerFields = append(headerFields, hpack.HeaderField{Name: ":scheme", Value: "http"})
+	headerFields = append(headerFields, hpack.HeaderField{Name: ":path", Value: url.GetParam(":path", "")}) // added when invoke, parse grpc 'method' to :path
+	headerFields = append(headerFields, hpack.HeaderField{Name: ":authority", Value: url.Location})
+	headerFields = append(headerFields, hpack.HeaderField{Name: "content-type", Value: url.GetParam("content-type", "application/grpc")})
+	headerFields = append(headerFields, hpack.HeaderField{Name: "user-agent", Value: "grpc-go/1.35.0-dev"})
+	headerFields = append(headerFields, hpack.HeaderField{Name: "tri-service-version", Value: getCtxVaSave(ctx, "tri-service-version")})
+	headerFields = append(headerFields, hpack.HeaderField{Name: "tri-service-group", Value: getCtxVaSave(ctx, "tri-service-group")})
+	headerFields = append(headerFields, hpack.HeaderField{Name: "tri-req-id", Value: getCtxVaSave(ctx, "tri-req-id")})
+	headerFields = append(headerFields, hpack.HeaderField{Name: "tri-trace-traceid", Value: getCtxVaSave(ctx, "tri-trace-traceid")})
+	headerFields = append(headerFields, hpack.HeaderField{Name: "tri-trace-rpcid", Value: getCtxVaSave(ctx, "tri-trace-rpcid")})
+	headerFields = append(headerFields, hpack.HeaderField{Name: "tri-trace-proto-bin", Value: getCtxVaSave(ctx, "tri-trace-proto-bin")})
+	headerFields = append(headerFields, hpack.HeaderField{Name: "tri-unit-info", Value: getCtxVaSave(ctx, "tri-unit-info")})
+	return headerFields
+}
+
+func getCtxVaSave(ctx context.Context, field string) string {
+	val, ok := ctx.Value(field).(string)
+	if ok {
+		return val
+	}
+	return ""
+}
+
+// ReadFromH2MetaHeader read meta header field from h2 header, and parse it to ProtocolHeader as user defined
+func (t TripleHeaderHandler) ReadFromH2MetaHeader(frame *http2.MetaHeadersFrame) remoting.ProtocolHeader {
+	tripleHeader := &TripleHeader{
+		streamID: frame.StreamID,
+	}
+	for _, f := range frame.Fields {
+		switch f.Name {
+		case "tri-service-version":
+			tripleHeader.ServiceVersion = f.Value
+		case "tri-service-group":
+			tripleHeader.ServiceGroup = f.Value
+		case "tri-req-id":
+			tripleHeader.RPCID = f.Value
+		case "tri-trace-traceid":
+			tripleHeader.TracingID = f.Value
+		case "tri-trace-rpcid":
+			tripleHeader.TracingRPCID = f.Value
+		case "tri-trace-proto-bin":
+			tripleHeader.TracingContext = f.Value
+		case "tri-unit-info":
+			tripleHeader.ClusterInfo = f.Value
+		case "content-type":
+			tripleHeader.ContentType = f.Value
+		case "grpc-encoding":

Review comment:
       remark them, pls.

##########
File path: remoting/dubbo3/stream.go
##########
@@ -0,0 +1,176 @@
+/*
+ * 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 dubbo3
+
+import (

Review comment:
       split it, pls.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For additional commands, e-mail: notifications-help@dubbo.apache.org