-
Notifications
You must be signed in to change notification settings - Fork 2
/
catena.go
78 lines (62 loc) · 1.92 KB
/
catena.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
// Package catena aides gRPC interceptor catenation.
package catena
import (
"golang.org/x/net/context"
"google.golang.org/grpc"
)
// UnaryServerCatena ...
type UnaryServerCatena struct {
is []grpc.UnaryServerInterceptor
}
// NewUnaryServerCatena ...
func NewUnaryServerCatena(is ...grpc.UnaryServerInterceptor) *UnaryServerCatena {
return &UnaryServerCatena{is: is}
}
func appendInterceptors(is []grpc.UnaryServerInterceptor, ais ...grpc.UnaryServerInterceptor) []grpc.UnaryServerInterceptor {
lcur := len(is)
ltot := lcur + len(ais)
if ltot > cap(is) {
nis := make([]grpc.UnaryServerInterceptor, ltot)
copy(nis, is)
is = nis
}
copy(is[lcur:], ais)
return is
}
// Append ...
func (c *UnaryServerCatena) Append(is ...grpc.UnaryServerInterceptor) *UnaryServerCatena {
c = NewUnaryServerCatena(appendInterceptors(c.is, is...)...)
return c
}
// Merge ...
func (c *UnaryServerCatena) Merge(cs ...*UnaryServerCatena) *UnaryServerCatena {
for k := range cs {
c = NewUnaryServerCatena(appendInterceptors(c.is, cs[k].is...)...)
}
return c
}
// Copy ...
func (c *UnaryServerCatena) Copy(catena *UnaryServerCatena) {
c.is = make([]grpc.UnaryServerInterceptor, len(catena.is))
for k := range catena.is {
c.is[k] = catena.is[k]
}
}
// Interceptor ...
func (c *UnaryServerCatena) Interceptor() grpc.UnaryServerInterceptor {
return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
concat := func(wrap grpc.UnaryServerInterceptor, h grpc.UnaryHandler) grpc.UnaryHandler {
return func(outerCtx context.Context, outerReq interface{}) (interface{}, error) {
return wrap(outerCtx, outerReq, info, h)
}
}
for i := len(c.is) - 1; i >= 0; i-- {
handler = concat(c.is[i], handler)
}
return handler(ctx, req)
}
}
// ServerOption ...
func (c *UnaryServerCatena) ServerOption() grpc.ServerOption {
return grpc.UnaryInterceptor(c.Interceptor())
}