This repository has been archived by the owner on Jan 8, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 330
/
grpc.go
88 lines (72 loc) · 2.17 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
package server
import (
"time"
"github.com/golang/protobuf/ptypes/empty"
"github.com/oklog/run"
"google.golang.org/grpc"
"google.golang.org/grpc/reflection"
pb "github.com/hashicorp/waypoint/internal/server/gen"
)
// grpcInit initializes the gRPC server and adds it to the run group.
func grpcInit(group *run.Group, opts *options) error {
log := opts.Logger.Named("grpc")
// Get our server info immediately
resp, err := opts.Service.GetVersionInfo(opts.Context, &empty.Empty{})
if err != nil {
return err
}
var so []grpc.ServerOption
so = append(so,
grpc.ChainUnaryInterceptor(
// Insert our logger and also log req/resp
logUnaryInterceptor(log, false),
// Protocol version negotiation
versionUnaryInterceptor(resp.Info),
),
grpc.ChainStreamInterceptor(
// Insert our logger and log
logStreamInterceptor(log, false),
// Protocol version negotiation
versionStreamInterceptor(resp.Info),
),
)
if opts.AuthChecker != nil {
so = append(so,
grpc.ChainUnaryInterceptor(authUnaryInterceptor(opts.AuthChecker)),
grpc.ChainStreamInterceptor(authStreamInterceptor(opts.AuthChecker)),
)
}
s := grpc.NewServer(so...)
opts.grpcServer = s
// Register the reflection service. This makes using tools like grpcurl
// easier. It makes it slightly easier for malicious users to know about
// the service but I think they'd figure out its a waypoint server
// easy enough.
reflection.Register(s)
// Register our server
pb.RegisterWaypointServer(s, opts.Service)
// Add our gRPC server to the run group
group.Add(func() error {
// Serve traffic
ln := opts.GRPCListener
log.Info("starting gRPC server", "addr", ln.Addr().String())
return s.Serve(ln)
}, func(err error) {
// Graceful in a goroutine so we can timeout
gracefulCh := make(chan struct{})
go func() {
defer close(gracefulCh)
log.Info("shutting down gRPC server")
s.GracefulStop()
}()
select {
case <-gracefulCh:
// After a timeout we just forcibly exit. Our gRPC endpoints should
// be fairly quick and their operations are atomic so we just kill
// the connections after a few seconds.
case <-time.After(2 * time.Second):
s.Stop()
}
})
return nil
}