This commit is contained in:
crusader 2017-11-03 15:33:50 +09:00
parent 3a505e6883
commit b8600ca9a4
2 changed files with 40 additions and 38 deletions

View File

@ -77,16 +77,16 @@ func (rr *rpcRegistry) Invoke(codec protocol.RegistryCodec) (result interface{},
// Decode the args. // Decode the args.
var in []reflect.Value var in []reflect.Value
params := methodSpec.getInterfaces() pValues, pInstances := methodSpec.getParamValues()
if nil != params && 0 < len(params) { if nil != pInstances && 0 < len(pInstances) {
if errRead := codec.ReadParams(&params); errRead != nil { if errRead := codec.ReadParams(&pInstances); errRead != nil {
return nil, errRead return nil, errRead
} }
pCount := len(params) pCount := len(pInstances)
in = make([]reflect.Value, pCount+1) in = make([]reflect.Value, pCount+1)
for indexI := 0; indexI < pCount; indexI++ { for indexI := 0; indexI < pCount; indexI++ {
in[indexI+1] = reflect.ValueOf(params[indexI]) in[indexI+1] = pValues[indexI]
} }
} else { } else {
in = make([]reflect.Value, 1) in = make([]reflect.Value, 1)

View File

@ -28,26 +28,39 @@ type service struct {
type serviceMethod struct { type serviceMethod struct {
method reflect.Method // receiver method method reflect.Method // receiver method
paramTypes []reflect.Type // type of the request argument paramTypes []reflect.Type // type of the request argument
paramValues []reflect.Value
returnType reflect.Type // type of the response argument returnType reflect.Type // type of the response argument
returnValue reflect.Value
} }
func (sm *serviceMethod) getInterfaces() (instances []interface{}) { func (sm *serviceMethod) getParamValues() (values []reflect.Value, instances []interface{}) {
if nil == sm.paramValues || 0 == len(sm.paramValues) { if nil == sm.paramTypes || 0 == len(sm.paramTypes) {
return nil return nil, nil
} }
pCount := len(sm.paramValues) pCount := len(sm.paramTypes)
values = make([]reflect.Value, pCount)
instances = make([]interface{}, pCount) instances = make([]interface{}, pCount)
for indexI := 0; indexI < pCount; indexI++ { for indexI := 0; indexI < pCount; indexI++ {
instances[indexI] = sm.paramValues[indexI].Interface() values[indexI] = getValue(sm.paramTypes[indexI])
instances[indexI] = values[indexI].Interface()
} }
return return
} }
func getValue(t reflect.Type) reflect.Value {
rt := t
if rt.Kind() == reflect.Ptr {
rt = rt.Elem()
}
rv := reflect.New(rt)
if rt.Kind() != reflect.Struct {
rv = reflect.Indirect(rv)
}
return rv
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// serviceMap // serviceMap
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -90,20 +103,19 @@ Loop:
} }
var paramTypes []reflect.Type var paramTypes []reflect.Type
var paramValues []reflect.Value
var returnType reflect.Type var returnType reflect.Type
var returnValue reflect.Value
pCount := mt.NumIn() - 1 pCount := mt.NumIn() - 1
if 0 < pCount { if 0 < pCount {
paramTypes = make([]reflect.Type, pCount) paramTypes = make([]reflect.Type, pCount)
paramValues = make([]reflect.Value, pCount)
for indexI := 0; indexI < pCount; indexI++ { for indexI := 0; indexI < pCount; indexI++ {
if paramTypes[indexI], paramValues[indexI], err = validateType(mt.In(indexI + 1)); nil != err { pt := mt.In(indexI + 1)
if err = validateType(mt.In(indexI + 1)); nil != err {
return err return err
} }
paramTypes[indexI] = pt
} }
} }
@ -120,9 +132,11 @@ Loop:
if t := mt.Out(1); t != typeOfError { if t := mt.Out(1); t != typeOfError {
continue Loop continue Loop
} }
if returnType, returnValue, err = validateType(mt.Out(0)); nil != err { rt := mt.Out(0)
if err = validateType(rt); nil != err {
return err return err
} }
returnType = rt
default: default:
continue continue
} }
@ -130,9 +144,7 @@ Loop:
s.methods[m.Name] = &serviceMethod{ s.methods[m.Name] = &serviceMethod{
method: m, method: m,
paramTypes: paramTypes, paramTypes: paramTypes,
paramValues: paramValues,
returnType: returnType, returnType: returnType,
returnValue: returnValue,
} }
} }
if len(s.methods) == 0 { if len(s.methods) == 0 {
@ -150,21 +162,11 @@ Loop:
return nil return nil
} }
func validateType(t reflect.Type) (rt reflect.Type, rv reflect.Value, err error) { func validateType(t reflect.Type) error {
if t.Kind() == reflect.Struct { if t.Kind() == reflect.Struct {
err = fmt.Errorf("Type is Struct. Pass by reference, i.e. *%s", t) return fmt.Errorf("Type is Struct. Pass by reference, i.e. *%s", t)
return
} }
rt = t return nil
if t.Kind() == reflect.Ptr {
rt = t.Elem()
}
rv = reflect.New(rt)
if rt.Kind() != reflect.Struct {
rv = reflect.Indirect(rv)
}
return
} }
// get returns a registered service given a method name. // get returns a registered service given a method name.