diff --git a/common/proxy/proxy.go b/common/proxy/proxy.go index fe4c003306360af928a0b1a6612042e9811a9af3..44abac14398e07ac2cbc96b799cfada7e1f0ad19 100644 --- a/common/proxy/proxy.go +++ b/common/proxy/proxy.go @@ -19,6 +19,7 @@ package proxy import ( "reflect" + "sync" ) import ( @@ -34,6 +35,8 @@ type Proxy struct { invoke protocol.Invoker callBack interface{} attachments map[string]string + + once sync.Once } var typError = reflect.Zero(reflect.TypeOf((*error)(nil)).Elem()).Type() @@ -166,7 +169,9 @@ func (p *Proxy) Implement(v common.RPCService) { } } - p.rpc = v + p.once.Do(func() { + p.rpc = v + }) } diff --git a/config/config_loader.go b/config/config_loader.go index 2560b78bd15686d221cdb7f2e0e613954688e20e..7b40a26e5a01162bb94efef316dbb00a5d2ccc6a 100644 --- a/config/config_loader.go +++ b/config/config_loader.go @@ -19,6 +19,7 @@ package config import ( "fmt" + "github.com/apache/dubbo-go/common" "io/ioutil" "log" "os" @@ -203,8 +204,13 @@ func loadProtocol(protocolsIds string, protocols []ProtocolConfig) []ProtocolCon return returnProtocols } +var ( + refConfigs map[string]*ReferenceConfig // record reference config loaded + srvConfigs map[string]*ServiceConfig // record service config loaded +) + // Dubbo Init -func Load() (map[string]*ReferenceConfig, map[string]*ServiceConfig) { +func Load() (int, int) { var refMap map[string]*ReferenceConfig var srvMap map[string]*ServiceConfig @@ -217,13 +223,13 @@ func Load() (map[string]*ReferenceConfig, map[string]*ServiceConfig) { for index := 0; index < length; index++ { con := &consumerConfig.References[index] rpcService := GetConsumerService(con.InterfaceName) + con.Refer() + refMap[con.InterfaceName] = con if rpcService == nil { logger.Warnf("%s is not exsist!", con.InterfaceName) continue } - con.Refer() con.Implement(rpcService) - refMap[con.InterfaceName] = con } //wait for invoker is available, if wait over default 3s, then panic @@ -278,5 +284,17 @@ func Load() (map[string]*ReferenceConfig, map[string]*ServiceConfig) { } } - return refMap, srvMap + refConfigs = refMap + srvConfigs = srvMap + return len(refMap), len(srvMap) +} + +// get rpc service for consumer +func GetRPCService(name string) common.RPCService { + return refConfigs[name].GetRPCService() +} + +// create rpc service for consumer +func RPCService(service common.RPCService) { + refConfigs[service.Service()].Implement(service) } diff --git a/config/config_loader_test.go b/config/config_loader_test.go index 7c3343fd35a1ce9d3e519d3f45435be775755bdf..9d062ce2fc5a043ceb07f9175ba5f62eba055abd 100644 --- a/config/config_loader_test.go +++ b/config/config_loader_test.go @@ -59,17 +59,25 @@ func TestLoad(t *testing.T) { doInit() doinit() - SetConsumerService(&MockService{}) - SetProviderService(&MockService{}) + ms := &MockService{} + SetConsumerService(ms) + SetProviderService(ms) extension.SetProtocol("registry", GetProtocol) extension.SetCluster("registryAware", cluster_impl.NewRegistryAwareCluster) extension.SetProxyFactory("default", proxy_factory.NewDefaultProxyFactory) consumerConfig.References[0].Registries = []ConfigRegistry{"shanghai_reg1"} - refConfigs, svcConfigs := Load() - assert.NotEqual(t, 0, len(refConfigs)) - assert.NotEqual(t, 0, len(svcConfigs)) + refLen, svcLen := Load() + assert.NotEqual(t, 0, refLen) + assert.NotEqual(t, 0, svcLen) + + assert.Equal(t, ms, GetRPCService(ms.Service())) + ms2 := &struct { + MockService + }{} + RPCService(ms2) + assert.NotEqual(t, ms2, GetRPCService(ms2.Service())) conServices = map[string]common.RPCService{} proServices = map[string]common.RPCService{} diff --git a/examples/dubbo/go-client/app/client.go b/examples/dubbo/go-client/app/client.go index 6167fbc8e7b0743f807775d1c414110159d01449..14bafeddceb33837434096199a365cc4d142d275 100644 --- a/examples/dubbo/go-client/app/client.go +++ b/examples/dubbo/go-client/app/client.go @@ -57,13 +57,13 @@ func main() { hessian.RegisterJavaEnum(Gender(WOMAN)) hessian.RegisterPOJO(&User{}) - conMap, _ := config.Load() - if conMap == nil { + conLen, _ := config.Load() + if conLen == 0 { panic("conMap is nil") } println("\n\n\necho") - res, err := conMap["com.ikurento.user.UserProvider"].GetRPCService().(*UserProvider).Echo(context.TODO(), "OK") + res, err := userProvider.Echo(context.TODO(), "OK") if err != nil { panic(err) } @@ -73,21 +73,21 @@ func main() { println("\n\n\nstart to test dubbo") user := &User{} - err = conMap["com.ikurento.user.UserProvider"].GetRPCService().(*UserProvider).GetUser(context.TODO(), []interface{}{"A003"}, user) + err = userProvider.GetUser(context.TODO(), []interface{}{"A003"}, user) if err != nil { panic(err) } println("response result: %v", user) println("\n\n\nstart to test dubbo - GetUser0") - ret, err := conMap["com.ikurento.user.UserProvider"].GetRPCService().(*UserProvider).GetUser0("A003", "Moorse") + ret, err := userProvider.GetUser0("A003", "Moorse") if err != nil { panic(err) } println("response result: %v", ret) println("\n\n\nstart to test dubbo - GetUsers") - ret1, err := conMap["com.ikurento.user.UserProvider"].GetRPCService().(*UserProvider).GetUsers([]interface{}{[]interface{}{"A002", "A003"}}) + ret1, err := userProvider.GetUsers([]interface{}{[]interface{}{"A002", "A003"}}) if err != nil { panic(err) } @@ -95,7 +95,7 @@ func main() { println("\n\n\nstart to test dubbo - getUser") user = &User{} - err = conMap["com.ikurento.user.UserProvider"].GetRPCService().(*UserProvider).GetUser2(context.TODO(), []interface{}{1}, user) + err = userProvider.GetUser2(context.TODO(), []interface{}{1}, user) if err != nil { println("getUser - error: %v", err) } else { @@ -104,13 +104,13 @@ func main() { println("\n\n\nstart to test dubbo - getErr") user = &User{} - err = conMap["com.ikurento.user.UserProvider"].GetRPCService().(*UserProvider).GetErr(context.TODO(), []interface{}{"A003"}, user) + err = userProvider.GetErr(context.TODO(), []interface{}{"A003"}, user) if err != nil { println("getErr - error: %v", err) } println("\n\n\nstart to test dubbo illegal method") - err = conMap["com.ikurento.user.UserProvider"].GetRPCService().(*UserProvider).GetUser1(context.TODO(), []interface{}{"A003"}, user) + err = userProvider.GetUser1(context.TODO(), []interface{}{"A003"}, user) if err != nil { panic(err) } diff --git a/examples/dubbo/go-client/app/user.go b/examples/dubbo/go-client/app/user.go index 59e105109ecb7213a071ca9071737e14fff0869e..2fd29803c8d2b1262838a4dca34a0a38cacb5884 100644 --- a/examples/dubbo/go-client/app/user.go +++ b/examples/dubbo/go-client/app/user.go @@ -34,8 +34,10 @@ import ( type Gender hessian.JavaEnum +var userProvider = new(UserProvider) + func init() { - config.SetConsumerService(new(UserProvider)) + config.SetConsumerService(userProvider) } const ( diff --git a/examples/dubbo/go-server/app/server.go b/examples/dubbo/go-server/app/server.go index a5c89be7a6b36ddaaae8b515729aaccd203c19f1..2a032a624ca0fd636c587a32f0a604da6f7764b6 100644 --- a/examples/dubbo/go-server/app/server.go +++ b/examples/dubbo/go-server/app/server.go @@ -58,8 +58,8 @@ func main() { hessian.RegisterPOJO(&User{}) // ------------ - _, proMap := config.Load() - if proMap == nil { + _, proLen := config.Load() + if proLen == 0 { panic("proMap is nil") } diff --git a/examples/jsonrpc/go-client/app/client.go b/examples/jsonrpc/go-client/app/client.go index 30a4ed1692d650a2580c008dde6f834e2c29b81e..47d0b6064740d1ad996218991af2e3c0ec85ec9d 100644 --- a/examples/jsonrpc/go-client/app/client.go +++ b/examples/jsonrpc/go-client/app/client.go @@ -49,13 +49,13 @@ var ( // export APP_LOG_CONF_FILE="xxx" func main() { - conMap, _ := config.Load() - if conMap == nil { + conLen, _ := config.Load() + if conLen == 0 { panic("conMap is nil") } println("\n\n\necho") - res, err := conMap["com.ikurento.user.UserProvider"].GetRPCService().(*UserProvider).Echo(context.TODO(), "OK") + res, err := userProvider.Echo(context.TODO(), "OK") if err != nil { println("echo - error: %v", err) } else { @@ -66,21 +66,21 @@ func main() { println("\n\n\nstart to test jsonrpc") user := &JsonRPCUser{} - err = conMap["com.ikurento.user.UserProvider"].GetRPCService().(*UserProvider).GetUser(context.TODO(), []interface{}{"A003"}, user) + err = userProvider.GetUser(context.TODO(), []interface{}{"A003"}, user) if err != nil { panic(err) } println("response result: %v", user) println("\n\n\nstart to test jsonrpc - GetUser0") - ret, err := conMap["com.ikurento.user.UserProvider"].GetRPCService().(*UserProvider).GetUser0("A003", "Moorse") + ret, err := userProvider.GetUser0("A003", "Moorse") if err != nil { panic(err) } println("response result: %v", ret) println("\n\n\nstart to test jsonrpc - GetUsers") - ret1, err := conMap["com.ikurento.user.UserProvider"].GetRPCService().(*UserProvider).GetUsers([]interface{}{[]interface{}{"A002", "A003"}}) + ret1, err := userProvider.GetUsers([]interface{}{[]interface{}{"A002", "A003"}}) if err != nil { panic(err) } @@ -88,7 +88,7 @@ func main() { println("\n\n\nstart to test jsonrpc - getUser") user = &JsonRPCUser{} - err = conMap["com.ikurento.user.UserProvider"].GetRPCService().(*UserProvider).GetUser2(context.TODO(), []interface{}{1}, user) + err = userProvider.GetUser2(context.TODO(), []interface{}{1}, user) if err != nil { println("getUser - error: %v", err) } else { @@ -96,7 +96,7 @@ func main() { } println("\n\n\nstart to test jsonrpc illegal method") - err = conMap["com.ikurento.user.UserProvider"].GetRPCService().(*UserProvider).GetUser1(context.TODO(), []interface{}{"A003"}, user) + err = userProvider.GetUser1(context.TODO(), []interface{}{"A003"}, user) if err != nil { panic(err) } diff --git a/examples/jsonrpc/go-client/app/user.go b/examples/jsonrpc/go-client/app/user.go index 6e2a97081ce74b28424e9faa8a74194cf9ea141f..b6c1a2feaccaca027ed57eb0f0a934fac0d560f6 100644 --- a/examples/jsonrpc/go-client/app/user.go +++ b/examples/jsonrpc/go-client/app/user.go @@ -27,8 +27,10 @@ import ( "github.com/apache/dubbo-go/config" ) +var userProvider = new(UserProvider) + func init() { - config.SetConsumerService(new(UserProvider)) + config.SetConsumerService(userProvider) } type JsonRPCUser struct { diff --git a/examples/jsonrpc/go-server/app/server.go b/examples/jsonrpc/go-server/app/server.go index 45692b4d1259ef0a8a8c4d784575488184289658..ba747497bf608deadcb4e8392e3def30bebfc6f5 100644 --- a/examples/jsonrpc/go-server/app/server.go +++ b/examples/jsonrpc/go-server/app/server.go @@ -48,8 +48,8 @@ var ( // export APP_LOG_CONF_FILE="xxx" func main() { - _, proMap := config.Load() - if proMap == nil { + _, proLen := config.Load() + if proLen == 0 { panic("proMap is nil") } diff --git a/go.mod b/go.mod index 0527279e480323cb580815a857839f575a03aa20..65ab4e64ea23bfffc66f44cefb6b2d2da18526c4 100644 --- a/go.mod +++ b/go.mod @@ -1,8 +1,8 @@ module github.com/apache/dubbo-go require ( - github.com/dubbogo/getty v0.0.0-20190607120257-8b0e100a88af // indirect - github.com/dubbogo/hessian2 v0.0.0-20190607144249-afb8cbfad2cb // indirect + github.com/dubbogo/getty v0.0.0-20190607120257-8b0e100a88af + github.com/dubbogo/hessian2 v0.0.0-20190607144249-afb8cbfad2cb github.com/pkg/errors v0.8.1 github.com/samuel/go-zookeeper v0.0.0-20180130194729-c4fab1ac1bec github.com/stretchr/testify v1.3.0 diff --git a/go.sum b/go.sum index 8617076c140fc5d600112466c28eb5acb523ea4a..62cc820e0e07220fa1723cd0709a5092e36c0727 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,13 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dubbogo/getty v0.0.0-20190607120257-8b0e100a88af h1:vvXNXyq5uIlf+KlTduhRKY4hBBBjgCUNreT1yIfKftw= github.com/dubbogo/getty v0.0.0-20190607120257-8b0e100a88af/go.mod h1:cRMSuoCmwc5lULFFnYZTxyCfZhObmRTNbS7XRnPNHSo= +github.com/dubbogo/hessian2 v0.0.0-20190607144249-afb8cbfad2cb h1:oN6hFLXbT/iDUO8qE4NZtvh89F/7VoAQ1LDxHJdmEH4= github.com/dubbogo/hessian2 v0.0.0-20190607144249-afb8cbfad2cb/go.mod h1:XFGDn4oSZX26zkcfhkM/fCJrOqwQJxk/xgWW1KMJBKM= +github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -21,6 +25,7 @@ go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/ go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53 h1:kcXqo9vE6fsZY5X5Rd7R1l7fTgnWaDCVmln65REefiE= golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=