Skip to content

Commit

Permalink
Merge pull request #98 from fangyincheng/imp
Browse files Browse the repository at this point in the history
Imp: some improvements
  • Loading branch information
AlexStocks authored Jun 19, 2019
2 parents 23f39b2 + 72f5336 commit 10d0f0f
Show file tree
Hide file tree
Showing 68 changed files with 666 additions and 335 deletions.
5 changes: 4 additions & 1 deletion common/constant/default.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ const (
DEFAULT_LOADBALANCE = "random"
DEFAULT_RETRIES = 2
DEFAULT_PROTOCOL = "dubbo"
DEFAULT_VERSION = ""
DEFAULT_REG_TIMEOUT = "10s"
DEFAULT_CLUSTER = "failover"
)
Expand All @@ -37,3 +36,7 @@ const (
DEFAULT_REFERENCE_FILTERS = ""
ECHO = "$echo"
)

const (
ANY_VALUE = "*"
)
1 change: 1 addition & 0 deletions common/constant/key.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ const (
WEIGHT_KEY = "weight"
WARMUP_KEY = "warmup"
RETRIES_KEY = "retries"
BEAN_NAME = "bean.name"
)

const (
Expand Down
4 changes: 2 additions & 2 deletions common/logger/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func init() {
logConfFile := os.Getenv(constant.APP_LOG_CONF_FILE)
err := InitLog(logConfFile)
if err != nil {
log.Printf("[InitLog] error: %v", err)
log.Printf("[InitLog] warn: %v", err)
}
}

Expand Down Expand Up @@ -110,7 +110,7 @@ func InitLogger(conf *zap.Config) {
} else {
zapLoggerConfig = *conf
}
zapLogger, _ := zapLoggerConfig.Build()
zapLogger, _ := zapLoggerConfig.Build(zap.AddCallerSkip(1))
logger = zapLogger.Sugar()
}

Expand Down
42 changes: 24 additions & 18 deletions common/proxy/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package proxy

import (
"reflect"
"sync"
)

import (
Expand All @@ -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()
Expand Down Expand Up @@ -78,23 +81,31 @@ func (p *Proxy) Implement(v common.RPCService) {
methodName = "$echo"
}

start := 0
end := len(in)
if in[0].Type().String() == "context.Context" {
start += 1
}
if len(outs) == 1 {
end -= 1
reply = in[len(in)-1]
} else {
if len(outs) == 2 {
if outs[0].Kind() == reflect.Ptr {
reply = reflect.New(outs[0].Elem())
} else {
reply = reflect.New(outs[0])
}
} else {
reply = valueOf
}

start := 0
end := len(in)
if end > 0 {
if in[0].Type().String() == "context.Context" {
start += 1
}
if len(outs) == 1 && in[end-1].Type().Kind() == reflect.Ptr {
end -= 1
reply = in[len(in)-1]
}
}

if v, ok := in[start].Interface().([]interface{}); ok && end-start == 1 {
if end-start <= 0 {
inArr = []interface{}{}
} else if v, ok := in[start].Interface().([]interface{}); ok && end-start == 1 {
inArr = v
} else {
inArr = make([]interface{}, end-start)
Expand Down Expand Up @@ -134,7 +145,6 @@ func (p *Proxy) Implement(v common.RPCService) {
}
f := valueOfElem.Field(i)
if f.Kind() == reflect.Func && f.IsValid() && f.CanSet() {
inNum := t.Type.NumIn()
outNum := t.Type.NumOut()

if outNum != 1 && outNum != 2 {
Expand All @@ -149,12 +159,6 @@ func (p *Proxy) Implement(v common.RPCService) {
continue
}

// reply must be Ptr when outNum == 1
if outNum == 1 && t.Type.In(inNum-1).Kind() != reflect.Ptr {
logger.Warnf("reply type of method %q is not a pointer", t.Name)
continue
}

var funcOuts = make([]reflect.Type, outNum)
for i := 0; i < outNum; i++ {
funcOuts[i] = t.Type.Out(i)
Expand All @@ -166,7 +170,9 @@ func (p *Proxy) Implement(v common.RPCService) {
}
}

p.rpc = v
p.once.Do(func() {
p.rpc = v
})

}

Expand Down
2 changes: 1 addition & 1 deletion common/proxy/proxy_factory/default.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,6 @@ func (factory *DefaultProxyFactory) GetProxy(invoker protocol.Invoker, url *comm
return proxy.NewProxy(invoker, nil, attachments)
}
func (factory *DefaultProxyFactory) GetInvoker(url common.URL) protocol.Invoker {
//TODO:yincheng need to do the service invoker refactor
// todo: call service
return protocol.NewBaseInvoker(url)
}
9 changes: 6 additions & 3 deletions common/proxy/proxy_factory/default_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,25 @@ import (
"testing"
)

import (
"github.com/stretchr/testify/assert"
)

import (
"github.com/apache/dubbo-go/common"
"github.com/apache/dubbo-go/protocol"
"github.com/stretchr/testify/assert"
)

func Test_GetProxy(t *testing.T) {
proxyFactory := NewDefaultProxyFactory()
url := common.NewURLWithOptions("testservice")
url := common.NewURLWithOptions()
proxy := proxyFactory.GetProxy(protocol.NewBaseInvoker(*url), url)
assert.NotNil(t, proxy)
}

func Test_GetInvoker(t *testing.T) {
proxyFactory := NewDefaultProxyFactory()
url := common.NewURLWithOptions("testservice")
url := common.NewURLWithOptions()
invoker := proxyFactory.GetInvoker(*url)
assert.True(t, invoker.IsAvailable())
}
25 changes: 11 additions & 14 deletions common/proxy/proxy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,10 @@ import (

type TestService struct {
MethodOne func(context.Context, int, bool, *interface{}) error
MethodTwo func([]interface{}, *interface{}) error
MethodTwo func([]interface{}) error
MethodThree func(int, bool) (interface{}, error)
MethodFour func(int, bool) (*interface{}, error) `dubbo:"methodFour"`
MethodFive func() error
Echo func(interface{}, *interface{}) error
}

Expand All @@ -64,19 +65,25 @@ func TestProxy_Implement(t *testing.T) {
p := NewProxy(invoker, nil, map[string]string{constant.ASYNC_KEY: "false"})
s := &TestService{}
p.Implement(s)

err := p.Get().(*TestService).MethodOne(nil, 0, false, nil)
assert.NoError(t, err)
err = p.Get().(*TestService).MethodTwo(nil, nil)

err = p.Get().(*TestService).MethodTwo(nil)
assert.NoError(t, err)
ret, err := p.Get().(*TestService).MethodThree(0, false)
assert.NoError(t, err)
assert.Nil(t, ret) // ret is nil, because it doesn't be injection yet

ret2, err := p.Get().(*TestService).MethodFour(0, false)
assert.NoError(t, err)
assert.Equal(t, "*interface {}", reflect.TypeOf(ret2).String())
err = p.Get().(*TestService).Echo(nil, nil)
assert.NoError(t, err)

err = p.Get().(*TestService).MethodFive()
assert.NoError(t, err)

// inherit & lowercase
p.rpc = nil
type S1 struct {
Expand Down Expand Up @@ -108,24 +115,14 @@ func TestProxy_Implement(t *testing.T) {
p.Implement(s2)
assert.Nil(t, s2.MethodOne)

// reply type
// returns type
p.rpc = nil
type S3 struct {
TestService
MethodOne func(context.Context, []interface{}, struct{}) error
MethodOne func(context.Context, []interface{}, *struct{}) interface{}
}
s3 := &S3{TestService: *s}
p.Implement(s3)
assert.Nil(t, s3.MethodOne)

// returns type
p.rpc = nil
type S4 struct {
TestService
MethodOne func(context.Context, []interface{}, *struct{}) interface{}
}
s4 := &S4{TestService: *s}
p.Implement(s4)
assert.Nil(t, s4.MethodOne)

}
37 changes: 22 additions & 15 deletions common/rpc_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ type RPCService interface {
Version() string
}

// for lowercase func
// func MethodMapper() map[string][string] {
// return map[string][string]{}
// }
const METHOD_MAPPER = "MethodMapper"

var (
// Precompute the reflect type for error. Can't use error directly
// because Typeof takes an empty interface value. This is annoying.
Expand Down Expand Up @@ -210,20 +216,26 @@ func isExportedOrBuiltinType(t reflect.Type) bool {
// suitableMethods returns suitable Rpc methods of typ
func suitableMethods(typ reflect.Type) (string, map[string]*MethodType) {
methods := make(map[string]*MethodType)
mts := ""
var mts []string
logger.Debugf("[%s] NumMethod is %d", typ.String(), typ.NumMethod())
method, ok := typ.MethodByName(METHOD_MAPPER)
var methodMapper map[string]string
if ok && method.Type.NumIn() == 1 && method.Type.NumOut() == 1 && method.Type.Out(0).String() == "map[string]string" {
methodMapper = method.Func.Call([]reflect.Value{reflect.New(typ.Elem())})[0].Interface().(map[string]string)
}

for m := 0; m < typ.NumMethod(); m++ {
method := typ.Method(m)
method = typ.Method(m)
if mt := suiteMethod(method); mt != nil {
methods[method.Name] = mt
if m == 0 {
mts += method.Name
} else {
mts += "," + method.Name
methodName, ok := methodMapper[method.Name]
if !ok {
methodName = method.Name
}
methods[methodName] = mt
mts = append(mts, methodName)
}
}
return mts, methods
return strings.Join(mts, ","), methods
}

// suiteMethod returns a suitable Rpc methodType
Expand Down Expand Up @@ -256,12 +268,7 @@ func suiteMethod(method reflect.Method) *MethodType {
}

// replyType
if outNum == 1 {
if mtype.In(inNum-1).Kind() != reflect.Ptr {
logger.Errorf("reply type of method %q is not a pointer %v", mname, replyType)
return nil
}
} else {
if outNum == 2 {
replyType = mtype.Out(0)
if !isExportedOrBuiltinType(replyType) {
logger.Errorf("reply type of method %s not exported{%v}", mname, replyType)
Expand All @@ -272,7 +279,7 @@ func suiteMethod(method reflect.Method) *MethodType {
index := 1

// ctxType
if mtype.In(1).String() == "context.Context" {
if inNum > 1 && mtype.In(1).String() == "context.Context" {
ctxType = mtype.In(1)
index = 2
}
Expand Down
Loading

0 comments on commit 10d0f0f

Please sign in to comment.