From d68c44e689eb15c4617d13362fe01e28ec23f069 Mon Sep 17 00:00:00 2001 From: fangyincheng <fangyincheng@sina.com> Date: Mon, 29 Apr 2019 15:04:10 +0800 Subject: [PATCH] Tst&Fix: add dubbo protocol test and fix bug --- config/rpc_service.go | 26 +++++----- go.mod | 9 +--- go.sum | 8 --- protocol/dubbo/client.go | 19 +++++--- protocol/dubbo/dubbo_exporter.go | 6 ++- protocol/dubbo/dubbo_invoker.go | 2 +- protocol/dubbo/dubbo_protocol.go | 6 ++- protocol/dubbo/dubbo_protocol_test.go | 70 +++++++++++++++++++++++++++ protocol/dubbo/listener.go | 8 ++- protocol/dubbo/readwriter.go | 2 +- protocol/invoker.go | 4 +- protocol/jsonrpc/jsonrpc_exporter.go | 6 ++- protocol/jsonrpc/jsonrpc_invoker.go | 2 +- protocol/jsonrpc/jsonrpc_protocol.go | 6 ++- protocol/jsonrpc/server.go | 2 +- protocol/protocol.go | 33 ++++++++----- 16 files changed, 153 insertions(+), 56 deletions(-) create mode 100644 protocol/dubbo/dubbo_protocol_test.go diff --git a/config/rpc_service.go b/config/rpc_service.go index 3d1e0482f..3a627177e 100644 --- a/config/rpc_service.go +++ b/config/rpc_service.go @@ -26,7 +26,7 @@ var ( typeOfError = reflect.TypeOf((*error)(nil)).Elem() ServiceMap = &serviceMap{ - serviceMap: make(map[string]*Service), + serviceMap: make(map[string]map[string]*Service), } ) @@ -87,24 +87,28 @@ func (s *Service) Rcvr() reflect.Value { ////////////////////////// type serviceMap struct { - mutex sync.RWMutex // protects the serviceMap - serviceMap map[string]*Service // service name -> service + mutex sync.RWMutex // protects the serviceMap + serviceMap map[string]map[string]*Service // protocol -> service name -> service } -func (sm *serviceMap) GetService(name string) *Service { +func (sm *serviceMap) GetService(protocol, name string) *Service { sm.mutex.RLock() defer sm.mutex.RUnlock() - if s, ok := sm.serviceMap[name]; ok { - return s + if s, ok := sm.serviceMap[protocol]; ok { + if srv, ok := s[name]; ok { + return srv + } + return nil } return nil } -func (sm *serviceMap) Register(rcvr RPCService) (string, error) { +// todo:Register is called by 'ServiceConfig' +func (sm *serviceMap) Register(protocol string, rcvr RPCService) (string, error) { sm.mutex.Lock() defer sm.mutex.Unlock() - if sm.serviceMap == nil { - sm.serviceMap = make(map[string]*Service) + if sm.serviceMap[protocol] == nil { + sm.serviceMap[protocol] = make(map[string]*Service) } s := new(Service) @@ -123,7 +127,7 @@ func (sm *serviceMap) Register(rcvr RPCService) (string, error) { } sname = rcvr.Service() - if server := sm.GetService(sname); server == nil { + if server := sm.GetService(protocol, sname); server != nil { return "", jerrors.New("service already defined: " + sname) } s.name = sname @@ -138,7 +142,7 @@ func (sm *serviceMap) Register(rcvr RPCService) (string, error) { log.Error(s) return "", jerrors.New(s) } - sm.serviceMap[s.name] = s + sm.serviceMap[protocol][s.name] = s return strings.TrimSuffix(methods, ","), nil } diff --git a/go.mod b/go.mod index 5d8c0aec0..aa565e80b 100644 --- a/go.mod +++ b/go.mod @@ -4,15 +4,10 @@ require ( github.com/AlexStocks/getty v0.0.0-20190331201845-1ca64ac5a589 github.com/AlexStocks/goext v0.3.2 github.com/AlexStocks/log4go v1.0.2 - github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc // indirect - github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf // indirect github.com/dubbogo/hessian2 v0.0.0-20190410112310-f093e4436e31 github.com/juju/errors v0.0.0-20190207033735-e65537c515d7 - github.com/juju/utils v0.0.0-20180820210520-bf9cc5bdd62d - github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223 // indirect - github.com/prometheus/common v0.0.0-20181126121408-4724e9255275 github.com/samuel/go-zookeeper v0.0.0-20180130194729-c4fab1ac1bec - github.com/tevino/abool v0.0.0-20170917061928-9b9efcf221b5 // indirect - gopkg.in/alecthomas/kingpin.v2 v2.2.6 // indirect + github.com/stretchr/testify v1.3.0 + github.com/tevino/abool v0.0.0-20170917061928-9b9efcf221b5 gopkg.in/yaml.v2 v2.2.2 ) diff --git a/go.sum b/go.sum index b12dffcd7..583504cf1 100644 --- a/go.sum +++ b/go.sum @@ -8,10 +8,6 @@ github.com/AlexStocks/goext v0.3.2/go.mod h1:3M5j9Pjge4CdkNg2WIjRLUeoPedJHHKwkkg github.com/AlexStocks/log4go v1.0.2 h1:1K5WM8KjSUECaoXUl8FSF05KGeCJDfBrhKUBsxwUvhk= github.com/AlexStocks/log4go v1.0.2/go.mod h1:6kCCRo/orDo8mh5CEDOeuSSM674wBQ8M6E0K8dVOIz4= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/cheekybits/is v0.0.0-20150225183255-68e9c0620927/go.mod h1:h/aW8ynjgkuj+NQRlZcDbAbM1ORAbXjXX77sX7T289U= @@ -86,8 +82,6 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0j github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223 h1:F9x/1yl3T2AeKLr2AMdilSD8+f9bvMnNN8VS5iDtovc= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/name5566/leaf v0.0.0-20181103040206-1364c176dfbd h1:22rhYEzttbrnKjgYh5pifnDluXHHcJ3uSOi2l8Nw+9A= github.com/name5566/leaf v0.0.0-20181103040206-1364c176dfbd/go.mod h1:JrOIxq3vDxvtuEI7Kmm2yqkuBfuT9DMLFMnCyYHLaKM= github.com/name5566/leaf v0.0.0-20181103040206-1364c176dfbd/go.mod h1:JrOIxq3vDxvtuEI7Kmm2yqkuBfuT9DMLFMnCyYHLaKM= @@ -159,8 +153,6 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/protocol/dubbo/client.go b/protocol/dubbo/client.go index c1c63f807..2f1eed2ea 100644 --- a/protocol/dubbo/client.go +++ b/protocol/dubbo/client.go @@ -1,9 +1,7 @@ package dubbo import ( - "gopkg.in/yaml.v2" "io/ioutil" - "math/rand" "os" "strings" "sync" @@ -16,6 +14,7 @@ import ( log "github.com/AlexStocks/log4go" "github.com/dubbogo/hessian2" jerrors "github.com/juju/errors" + "gopkg.in/yaml.v2" ) import ( @@ -29,34 +28,40 @@ var ( errClientClosed = jerrors.New("client closed") errClientReadTimeout = jerrors.New("client read timeout") - conf *ClientConfig + clientConf *ClientConfig ) const CONF_CLIENT_FILE_PATH = "CONF_CLIENT_FILE_PATH" func init() { - rand.Seed(time.Now().UnixNano()) - conf = &ClientConfig{} // load clientconfig from *.yml path := os.Getenv(CONF_CLIENT_FILE_PATH) if path == "" { log.Info("CONF_CLIENT_FILE_PATH is null") + return } file, err := ioutil.ReadFile(path) if err != nil { log.Error(jerrors.Trace(err)) + return } + conf := &ClientConfig{} err = yaml.Unmarshal(file, conf) if err != nil { log.Error(jerrors.Trace(err)) + return } if err := conf.CheckValidity(); err != nil { log.Error("ClientConfig check failed: ", jerrors.Trace(err)) + return } + + clientConf = conf + } type CallOptions struct { @@ -127,9 +132,9 @@ func NewClient() *Client { c := &Client{ pendingResponses: make(map[SequenceType]*PendingResponse), - conf: *conf, + conf: *clientConf, } - c.pool = newGettyRPCClientConnPool(c, conf.PoolSize, time.Duration(int(time.Second)*conf.PoolTTL)) + c.pool = newGettyRPCClientConnPool(c, clientConf.PoolSize, time.Duration(int(time.Second)*clientConf.PoolTTL)) return c } diff --git a/protocol/dubbo/dubbo_exporter.go b/protocol/dubbo/dubbo_exporter.go index 274fdd301..111b1782f 100644 --- a/protocol/dubbo/dubbo_exporter.go +++ b/protocol/dubbo/dubbo_exporter.go @@ -1,5 +1,9 @@ package dubbo +import ( + "sync" +) + import ( "github.com/dubbo/dubbo-go/protocol" ) @@ -8,7 +12,7 @@ type DubboExporter struct { protocol.BaseExporter } -func NewDubboExporter(key string, invoker protocol.Invoker, exporterMap map[string]protocol.Exporter) *DubboExporter { +func NewDubboExporter(key string, invoker protocol.Invoker, exporterMap *sync.Map) *DubboExporter { return &DubboExporter{ BaseExporter: *protocol.NewBaseExporter(key, invoker, exporterMap), } diff --git a/protocol/dubbo/dubbo_invoker.go b/protocol/dubbo/dubbo_invoker.go index 9d737877c..c5882675b 100644 --- a/protocol/dubbo/dubbo_invoker.go +++ b/protocol/dubbo/dubbo_invoker.go @@ -26,7 +26,7 @@ type DubboInvoker struct { func NewDubboInvoker(url config.IURL, client *Client) *DubboInvoker { return &DubboInvoker{ - BaseInvoker: protocol.NewBaseInvoker(url), + BaseInvoker: *protocol.NewBaseInvoker(url), client: client, } } diff --git a/protocol/dubbo/dubbo_protocol.go b/protocol/dubbo/dubbo_protocol.go index 271d3727d..eb6807b69 100644 --- a/protocol/dubbo/dubbo_protocol.go +++ b/protocol/dubbo/dubbo_protocol.go @@ -62,7 +62,11 @@ func (dp *DubboProtocol) Destroy() { } func (dp *DubboProtocol) openServer(url config.URL) { - srv := NewServer(dp.ExporterMap()[url.Key()]) + exporter, ok := dp.ExporterMap().Load(url.Key()) + if !ok { + panic("[DubboProtocol]" + url.Key() + "is not existing") + } + srv := NewServer(exporter.(protocol.Exporter)) dp.serverMap[url.Location] = srv srv.Start(url) } diff --git a/protocol/dubbo/dubbo_protocol_test.go b/protocol/dubbo/dubbo_protocol_test.go new file mode 100644 index 000000000..9a7649ee4 --- /dev/null +++ b/protocol/dubbo/dubbo_protocol_test.go @@ -0,0 +1,70 @@ +package dubbo + +import ( + "context" + "testing" +) + +import ( + "github.com/stretchr/testify/assert" +) + +import ( + "github.com/dubbo/dubbo-go/config" + "github.com/dubbo/dubbo-go/protocol" +) + +func TestDubboProtocol_Export(t *testing.T) { + // Export + proto := GetProtocol() + url, err := config.NewURL(context.Background(), "dubbo://192.168.56.1:20000/com.ikurento.user.UserProvider?anyhost=true&"+ + "application=BDTService&category=providers&default.timeout=10000&dubbo=dubbo-provider-golang-1.0.0&"+ + "environment=dev&interface=com.ikurento.user.UserProvider&ip=192.168.56.1&methods=GetUser%2C&"+ + "module=dubbogo+user-info+server&org=ikurento.com&owner=ZX&pid=1447&revision=0.0.1&"+ + "side=provider&timeout=3000×tamp=1556509797245") + assert.NoError(t, err) + srvConf = &ServerConfig{} + exporter := proto.Export(protocol.NewBaseInvoker(url)) + + // make sure url + eq := exporter.GetInvoker().GetUrl().URLEqual(url) + assert.True(t, eq) + + // make sure exporterMap after 'Unexport' + _, ok := proto.(*DubboProtocol).ExporterMap().Load(url.Key()) + assert.True(t, ok) + exporter.Unexport() + _, ok = proto.(*DubboProtocol).ExporterMap().Load(url.Key()) + assert.False(t, ok) + + // make sure serverMap after 'Destroy' + _, ok = proto.(*DubboProtocol).serverMap[url.Location] + assert.True(t, ok) + proto.Destroy() + _, ok = proto.(*DubboProtocol).serverMap[url.Location] + assert.False(t, ok) +} + +func TestDubboProtocol_Refer(t *testing.T) { + // Refer + proto := GetProtocol() + url, err := config.NewURL(context.Background(), "dubbo://192.168.56.1:20000/com.ikurento.user.UserProvider?anyhost=true&"+ + "application=BDTService&category=providers&default.timeout=10000&dubbo=dubbo-provider-golang-1.0.0&"+ + "environment=dev&interface=com.ikurento.user.UserProvider&ip=192.168.56.1&methods=GetUser%2C&"+ + "module=dubbogo+user-info+server&org=ikurento.com&owner=ZX&pid=1447&revision=0.0.1&"+ + "side=provider&timeout=3000×tamp=1556509797245") + assert.NoError(t, err) + clientConf = &ClientConfig{} + invoker := proto.Refer(url) + + // make sure url + eq := invoker.GetUrl().URLEqual(url) + assert.True(t, eq) + + // make sure invokers after 'Destroy' + invokersLen := len(proto.(*DubboProtocol).Invokers()) + assert.Equal(t, 1, invokersLen) + proto.Destroy() + invokersLen = len(proto.(*DubboProtocol).Invokers()) + assert.Equal(t, 0, invokersLen) +} diff --git a/protocol/dubbo/listener.go b/protocol/dubbo/listener.go index 38a12e275..5835b3295 100644 --- a/protocol/dubbo/listener.go +++ b/protocol/dubbo/listener.go @@ -261,6 +261,12 @@ func (h *RpcServerHandler) callService(req *DubboPackage, ctx context.Context) { } svc := svcIf.(*config.Service) method := svc.Method()[req.Service.Method] + if method == nil { + log.Error("method not found!") + req.Header.ResponseStatus = hessian.Response_SERVICE_NOT_FOUND + req.Body = nil + return + } // prepare argv var argv reflect.Value @@ -280,7 +286,7 @@ func (h *RpcServerHandler) callService(req *DubboPackage, ctx context.Context) { // prepare replyv replyv := reflect.New(method.ReplyType().Elem()) var returnValues []reflect.Value - if method.CtxType == nil { + if method.CtxType() == nil { returnValues = method.Method().Func.Call([]reflect.Value{svc.Rcvr(), reflect.ValueOf(argvTmp), reflect.ValueOf(replyv.Interface())}) } else { if contextv := reflect.ValueOf(ctx); contextv.IsValid() { diff --git a/protocol/dubbo/readwriter.go b/protocol/dubbo/readwriter.go index be720e009..2c870da83 100644 --- a/protocol/dubbo/readwriter.go +++ b/protocol/dubbo/readwriter.go @@ -107,7 +107,7 @@ func (p *RpcServerPackageHandler) Read(ss getty.Session, data []byte) (interface "dubboVersion": dubboVersion, "argsTypes": argsTypes, "args": args, - "service": config.ServiceMap.GetService(pkg.Service.Target), + "service": config.ServiceMap.GetService(DUBBO, pkg.Service.Target), "attachments": attachments, } } diff --git a/protocol/invoker.go b/protocol/invoker.go index 922362864..03a39efa2 100644 --- a/protocol/invoker.go +++ b/protocol/invoker.go @@ -25,8 +25,8 @@ type BaseInvoker struct { destroyed bool } -func NewBaseInvoker(url config.IURL) BaseInvoker { - return BaseInvoker{ +func NewBaseInvoker(url config.IURL) *BaseInvoker { + return &BaseInvoker{ url: url, available: true, destroyed: false, diff --git a/protocol/jsonrpc/jsonrpc_exporter.go b/protocol/jsonrpc/jsonrpc_exporter.go index dd0918281..3c6c16cbb 100644 --- a/protocol/jsonrpc/jsonrpc_exporter.go +++ b/protocol/jsonrpc/jsonrpc_exporter.go @@ -1,5 +1,9 @@ package jsonrpc +import ( + "sync" +) + import ( "github.com/dubbo/dubbo-go/protocol" ) @@ -8,7 +12,7 @@ type JsonrpcExporter struct { protocol.BaseExporter } -func NewJsonrpcExporter(key string, invoker protocol.Invoker, exporterMap map[string]protocol.Exporter) *JsonrpcExporter { +func NewJsonrpcExporter(key string, invoker protocol.Invoker, exporterMap *sync.Map) *JsonrpcExporter { return &JsonrpcExporter{ BaseExporter: *protocol.NewBaseExporter(key, invoker, exporterMap), } diff --git a/protocol/jsonrpc/jsonrpc_invoker.go b/protocol/jsonrpc/jsonrpc_invoker.go index 38b929c02..36952d3e3 100644 --- a/protocol/jsonrpc/jsonrpc_invoker.go +++ b/protocol/jsonrpc/jsonrpc_invoker.go @@ -22,7 +22,7 @@ type JsonrpcInvoker struct { func NewJsonrpcInvoker(url config.IURL, client *HTTPClient) *JsonrpcInvoker { return &JsonrpcInvoker{ - BaseInvoker: protocol.NewBaseInvoker(url), + BaseInvoker: *protocol.NewBaseInvoker(url), client: client, } } diff --git a/protocol/jsonrpc/jsonrpc_protocol.go b/protocol/jsonrpc/jsonrpc_protocol.go index cb6cd5258..343e03ef3 100644 --- a/protocol/jsonrpc/jsonrpc_protocol.go +++ b/protocol/jsonrpc/jsonrpc_protocol.go @@ -67,7 +67,11 @@ func (jp *JsonrpcProtocol) Destroy() { } func (jp *JsonrpcProtocol) openServer(url config.URL) { - srv := NewServer(jp.ExporterMap()[url.Key()]) + exporter, ok := jp.ExporterMap().Load(url.Key()) + if !ok { + panic("[JsonrpcProtocol]" + url.Key() + "is not existing") + } + srv := NewServer(exporter.(protocol.Exporter)) jp.serverMap[url.Location] = srv srv.Start(url) } diff --git a/protocol/jsonrpc/server.go b/protocol/jsonrpc/server.go index 01950d3ab..465617b92 100644 --- a/protocol/jsonrpc/server.go +++ b/protocol/jsonrpc/server.go @@ -272,7 +272,7 @@ func serveRequest(ctx context.Context, } // get method - svc := config.ServiceMap.GetService(serviceName) + svc := config.ServiceMap.GetService(JSONRPC, serviceName) if svc == nil { codec.ReadBody(nil) return jerrors.New("cannot find svc " + serviceName) diff --git a/protocol/protocol.go b/protocol/protocol.go index a490ba4cb..601611515 100644 --- a/protocol/protocol.go +++ b/protocol/protocol.go @@ -1,8 +1,15 @@ package protocol +import ( + "sync" +) + +import ( + log "github.com/AlexStocks/log4go" +) + import ( "github.com/dubbo/dubbo-go/config" - "github.com/prometheus/common/log" ) // Extension - Protocol @@ -23,21 +30,21 @@ type Exporter interface { ///////////////////////////// type BaseProtocol struct { - exporterMap map[string]Exporter + exporterMap *sync.Map invokers []Invoker } func NewBaseProtocol() BaseProtocol { return BaseProtocol{ - exporterMap: make(map[string]Exporter), + exporterMap: new(sync.Map), } } func (bp *BaseProtocol) SetExporterMap(key string, exporter Exporter) { - bp.exporterMap[key] = exporter + bp.exporterMap.Store(key, exporter) } -func (bp *BaseProtocol) ExporterMap() map[string]Exporter { +func (bp *BaseProtocol) ExporterMap() *sync.Map { return bp.exporterMap } @@ -57,6 +64,7 @@ func (bp *BaseProtocol) Refer(url config.IURL) Invoker { return nil } +//Destroy will destroy all invoker and exporter, so it only is called once. func (bp *BaseProtocol) Destroy() { // destroy invokers for _, invoker := range bp.invokers { @@ -67,13 +75,14 @@ func (bp *BaseProtocol) Destroy() { bp.invokers = []Invoker{} // unexport exporters - for key, exporter := range bp.ExporterMap() { + bp.exporterMap.Range(func(key, exporter interface{}) bool { if exporter != nil { - exporter.Unexport() + exporter.(Exporter).Unexport() } else { - delete(bp.exporterMap, key) + bp.exporterMap.Delete(key) } - } + return true + }) } ///////////////////////////// @@ -83,10 +92,10 @@ func (bp *BaseProtocol) Destroy() { type BaseExporter struct { key string invoker Invoker - exporterMap map[string]Exporter + exporterMap *sync.Map } -func NewBaseExporter(key string, invoker Invoker, exporterMap map[string]Exporter) *BaseExporter { +func NewBaseExporter(key string, invoker Invoker, exporterMap *sync.Map) *BaseExporter { return &BaseExporter{ key: key, invoker: invoker, @@ -102,5 +111,5 @@ func (de *BaseExporter) GetInvoker() Invoker { func (de *BaseExporter) Unexport() { log.Info("Exporter unexport.") de.invoker.Destroy() - delete(de.exporterMap, de.key) + de.exporterMap.Delete(de.key) } -- GitLab