forked from danielvladco/go-proto-gql
/
grpc.go
98 lines (84 loc) · 2.66 KB
/
grpc.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
package server
import (
"context"
"log"
"time"
"github.com/danielvladco/go-proto-gql/pkg/reflection"
"github.com/jhump/protoreflect/desc"
"github.com/jhump/protoreflect/dynamic/grpcdynamic"
"google.golang.org/grpc"
"google.golang.org/protobuf/proto"
)
type Caller interface {
Call(ctx context.Context, svc *desc.ServiceDescriptor, rpc *desc.MethodDescriptor, message proto.Message) (proto.Message, error)
}
type caller struct {
serviceStub map[*desc.ServiceDescriptor]grpcdynamic.Stub
}
func NewReflectCaller(endpoints []string) (*caller, []*desc.FileDescriptor, []string, error) {
var descs []*desc.FileDescriptor
descsconn := map[*desc.FileDescriptor]*grpc.ClientConn{}
for _, e := range endpoints {
conn, err := grpc.Dial(e, grpc.WithInsecure())
if err != nil {
return nil, nil, nil, err
}
client := reflection.NewClient(conn)
tempdesc, err := client.ListPackages()
if err != nil {
return nil, nil, nil, err
}
for _, d := range tempdesc {
descsconn[d] = conn
descs = append(descs, d)
}
}
origServices := map[*desc.ServiceDescriptor]grpcdynamic.Stub{}
for _, d := range descs {
for _, svc := range d.GetServices() {
origServices[svc] = grpcdynamic.NewStub(descsconn[d])
}
}
var filesToGenerate []string
//var protoFiles []*descriptor.FileDescriptorProto
for _, d := range descs {
//p := d.AsFileDescriptorProto()
//n := fmt.Sprintf("_%d_%s", i, p.GetName())
//p.Name = &n
//gopkg := "github.com/danielvladco/go-proto-gql/reflect/grpcserver1/pb;pb"
//p.Options.GoPackage = &gopkg
filesToGenerate = append(filesToGenerate, d.AsFileDescriptorProto().GetName())
//protoFiles = append(protoFiles, p)
for _, dp := range getDeps(d) {
// protoFiles = append(protoFiles, dp.AsFileDescriptorProto())
descs = append(descs, dp)
}
}
return &caller{
serviceStub: origServices,
}, descs, filesToGenerate, nil
}
func getDeps(file *desc.FileDescriptor) []*desc.FileDescriptor {
mp := map[*desc.FileDescriptor]struct{}{}
getAllDependencies(file, mp)
deps := make([]*desc.FileDescriptor, len(mp))
i := 0
for dp := range mp {
deps[i] = dp
i++
}
return deps
}
func getAllDependencies(file *desc.FileDescriptor, files map[*desc.FileDescriptor]struct{}) {
deps := file.GetDependencies()
for _, d := range deps {
files[d] = struct{}{}
getAllDependencies(d, files)
}
}
func (c caller) Call(ctx context.Context, svc *desc.ServiceDescriptor, rpc *desc.MethodDescriptor, message proto.Message) (proto.Message, error) {
startTime := time.Now()
res, err := c.serviceStub[svc].InvokeRpc(ctx, rpc, message)
log.Printf("[INFO] grpc request took: %fms", float64(time.Since(startTime))/float64(time.Millisecond))
return res, err
}