cascaded server rpc call
This commit is contained in:
@ -117,7 +117,10 @@ func (r rpcReturnTypeImpl) Error() error {
|
||||
|
||||
// Error : RPCReturnType.Error 구현
|
||||
func (r rpcReturnTypeImpl) Value() interface{} {
|
||||
return r.value.Interface()
|
||||
if r.value.IsValid() {
|
||||
return r.value.Interface()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// MakeRPCReturn :
|
||||
@ -301,6 +304,7 @@ func ConvertInterface(from interface{}, toType reflect.Type) reflect.Value {
|
||||
|
||||
// ErrUnmarshalRequestFailed :
|
||||
var ErrUnmarshalRequestFailed = errors.New("Unmarshal failed at rpc handler")
|
||||
var ErrInvalidContext = errors.New("Invalid context")
|
||||
|
||||
// CallMethodInternal :
|
||||
func CallMethodInternal(receiver interface{}, context functionCallContext) (interface{}, error) {
|
||||
@ -351,6 +355,37 @@ func CallMethodInternal(receiver interface{}, context functionCallContext) (inte
|
||||
return nil, errors.New(fmt.Sprint("method is missing :", receiver, context.Method))
|
||||
}
|
||||
|
||||
func CallMethodWithInterface(receiver interface{}, context interface{}) (retval RPCReturnType, err error) {
|
||||
|
||||
if context2, ok := context.(map[string]interface{}); ok {
|
||||
var meta functionCallContext
|
||||
if method, ok2 := context2["Method"].(string); ok2 {
|
||||
meta.Method = method
|
||||
} else {
|
||||
return nil, ErrInvalidContext
|
||||
}
|
||||
|
||||
if args, ok2 := context2["Args"].([]interface{}); ok2 {
|
||||
meta.Args = args
|
||||
} else {
|
||||
return nil, ErrInvalidContext
|
||||
}
|
||||
|
||||
if v, err := CallMethodInternal(receiver, meta); err == nil {
|
||||
if cast, ok := v.(RPCReturnType); ok {
|
||||
if cast.Error() != nil {
|
||||
return nil, cast.Error()
|
||||
}
|
||||
return cast, nil
|
||||
} else {
|
||||
return nil, errors.New(fmt.Sprint("method should return only RPCReturnType", meta))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil, ErrInvalidContext
|
||||
}
|
||||
|
||||
// CallMethod :
|
||||
func CallMethod(receiver interface{}, context []byte) (retval RPCReturnType, err error) {
|
||||
defer func() {
|
||||
@ -361,27 +396,30 @@ func CallMethod(receiver interface{}, context []byte) (retval RPCReturnType, err
|
||||
}
|
||||
}()
|
||||
|
||||
var meta functionCallContext
|
||||
if err := json.Unmarshal(context, &meta); err != nil {
|
||||
var raw interface{}
|
||||
if err := json.Unmarshal(context, &raw); err != nil {
|
||||
fmt.Println(string(context))
|
||||
return nil, ErrUnmarshalRequestFailed
|
||||
} else {
|
||||
fmt.Printf("%+v\n", meta)
|
||||
}
|
||||
|
||||
var v interface{}
|
||||
v, err = CallMethodInternal(receiver, meta)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if meta, ok := raw.(map[string]interface{}); ok {
|
||||
|
||||
// v는 RPCReturnType이어야 한다.
|
||||
if cast, ok := v.(RPCReturnType); ok {
|
||||
if cast.Error() != nil {
|
||||
return nil, cast.Error()
|
||||
if methods, ok := meta["Methods"].([]interface{}); ok {
|
||||
// calling cascaded methods
|
||||
body := make([]interface{}, 0, len(methods))
|
||||
|
||||
for _, meta2 := range methods {
|
||||
if cast, err := CallMethodWithInterface(receiver, meta2.(map[string]interface{})); err == nil {
|
||||
body = append(body, cast.Value())
|
||||
continue
|
||||
}
|
||||
return MakeRPCReturn(nil, err), err
|
||||
}
|
||||
return MakeRPCReturn(body, nil), nil
|
||||
} else {
|
||||
return CallMethodWithInterface(receiver, meta)
|
||||
}
|
||||
return cast, nil
|
||||
}
|
||||
|
||||
return nil, errors.New(fmt.Sprint("method should return only RPCReturnType", meta))
|
||||
return nil, errors.New("Invalid context")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user