-
Notifications
You must be signed in to change notification settings - Fork 2
/
rpc_func.go
106 lines (98 loc) · 2.16 KB
/
rpc_func.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
package rpcx
import (
"errors"
"log"
"reflect"
)
type FuncDesc uint8
const (
ReqHasData FuncDesc = 0x01
RspHasData FuncDesc = 0x02
)
type rpcFunc struct {
name string
fun reflect.Value
inParamType reflect.Type
outParamType reflect.Type
mid middleware
handleFunc HandleFunc
handleFuncDesc FuncDesc
}
func (this *rpcFunc) decodeInParam(data []byte) (interface{}, error) {
// fastpath
if this.handleFuncDesc&ReqHasData == 0 {
// request in is nil
return nil, nil
}
// check reqHasData
if len(data) == 0 {
return reflect.Zero(this.inParamType).Interface(), nil
}
elementType := this.inParamType
isPtr := false
if this.inParamType.Kind() == reflect.Ptr {
elementType = this.inParamType.Elem()
isPtr = true
}
newOutValue := reflect.New(elementType)
newOut := newOutValue.Interface()
err := gRpcSerialization.UnMarshal(data, newOut)
if err != nil {
return nil, err
}
if !isPtr {
newOut = newOutValue.Elem().Interface()
}
return newOut, nil
}
var errInvokeErr = errors.New("invoke failed")
var errInParamNil = errors.New("inParam is nil")
// dont call this func directly
func (this *rpcFunc) ____invoke(c Context) {
ctx := c.(*contextImpl)
defer func() {
//
panicErr := recover()
if panicErr == nil {
return
}
if Debug {
panic(panicErr)
}
log.Printf("call [%s] error:%v\n", ctx.Method(), panicErr)
ctx.SetError(errInvokeErr)
}()
err := ctx.Error()
if err != nil {
return
}
var outParam interface{} = nil
var paramV []reflect.Value = nil
if this.handleFuncDesc&ReqHasData != 0 {
inParam := ctx.Request()
if inParam == nil {
ctx.SetError(errInParamNil)
return
}
paramV = []reflect.Value{reflect.ValueOf(ctx), reflect.ValueOf(inParam)}
} else {
paramV = []reflect.Value{reflect.ValueOf(ctx)}
}
retV := this.fun.Call(paramV)
rspErrIdx := -1
rspDataIdx := -1
if this.handleFuncDesc&RspHasData != 0 {
rspErrIdx = 1
rspDataIdx = 0
} else {
rspErrIdx = 0
}
if !retV[rspErrIdx].IsNil() { // check error
err = retV[rspErrIdx].Interface().(error)
ctx.SetError(err)
}
if rspDataIdx != -1 {
outParam = retV[rspDataIdx].Interface()
ctx.SetResponse(outParam)
}
}