-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathservice_handler.go
102 lines (76 loc) · 2.31 KB
/
service_handler.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
package easycall
import (
"reflect"
"time"
"github.com/panjf2000/ants/v2"
"github.com/starjiang/elog"
)
//ServiceHandler for EasyService
type ServiceHandler struct {
service interface{}
value reflect.Value
middlewares []*MiddlewareInfo
pool *ants.Pool
}
func NewServiceHandler(service interface{}, middlewares []*MiddlewareInfo) *ServiceHandler {
serviceHandler := &ServiceHandler{}
serviceHandler.service = service
serviceHandler.value = reflect.ValueOf(service)
pool, _ := ants.NewPool(EASYCALL_SERVICE_GO_POOL_SIZE, ants.WithNonblocking(true))
serviceHandler.pool = pool
mlen := len(middlewares)
finalFunc := func(req *Request, resp *Response, client *EasyConnection, next *MiddlewareInfo) {
serviceHandler.onRequest(req, resp, client)
}
final := &MiddlewareInfo{finalFunc, nil}
if mlen > 0 {
middlewares[mlen-1].Next = final
} else {
middlewares = append(middlewares, final)
}
serviceHandler.middlewares = middlewares
return serviceHandler
}
func (h *ServiceHandler) Dispatch(pkgData []byte, client *EasyConnection) {
err := h.pool.Submit(func() {
defer PanicHandler()
reqPkg, err := DecodeWithBodyData(pkgData)
if err != nil {
elog.Error("decode pkg fail:", err)
return
}
req := &Request{reqPkg.GetFormat(), reqPkg.GetHead(), reqPkg.GetBodyData(), time.Now(), make(map[string]interface{})}
resp := &Response{reqPkg.GetFormat(), reqPkg.GetHead(), nil}
h.middlewares[0].Middleware(req, resp, client, h.middlewares[0].Next)
})
if err != nil {
elog.Error("submit to pool fail,", err)
}
}
func (h *ServiceHandler) onRequest(req *Request, resp *Response, client *EasyConnection) {
m := h.value.MethodByName(req.head.Method)
if !m.IsValid() {
req.head.SetRet(ERROR_METHOD_NOT_FOUND)
req.head.SetMsg("method " + req.head.Method + " not found")
respPkg := NewPackageWithBody(req.format, req.head, make(map[string]interface{}))
pkgData, err := respPkg.EncodeWithBody()
if err != nil {
elog.Error("encode pkg fail:", err)
return
}
client.Send(pkgData)
return
}
in := []reflect.Value{
reflect.ValueOf(req),
reflect.ValueOf(resp),
}
m.Call(in)
respPkg := NewPackageWithBody(resp.format, resp.head, resp.body)
pkgData, err := respPkg.EncodeWithBody()
if err != nil {
elog.Error("encode pkg fail:", err)
return
}
client.Send(pkgData)
}