/
server.go
63 lines (53 loc) · 1.47 KB
/
server.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
package grpc
import (
"fmt"
"net"
"google.golang.org/grpc"
)
// Server handles gRPC requests to the service.
type Server struct {
*grpc.Server
listener net.Listener
closeFunc []func()
}
// Config holds service's settings.
type Config struct {
Addr string `envconfig:"ADDRESS" env:"ADDRESS" long:"address" default:"0.0.0.0:9100"`
}
// NewServer instantiates a gRPC server.
// When passing addr with an unspecified port or ":", use Addr().
func NewServer(addr string, opts ...grpc.ServerOption) (*Server, error) {
lis, err := net.Listen("tcp", addr)
if err != nil {
return nil, fmt.Errorf("listening failed: %w", err)
}
srv := grpc.NewServer(opts...)
return &Server{Server: srv, listener: lis}, nil
}
// AddCloseFunc adds a function to be called by the Close method.
// This eliminates the need for wrapping the Server.
func (s *Server) AddCloseFunc(f func()) {
s.closeFunc = append(s.closeFunc, f)
}
func (s *Server) Addr() string {
return s.listener.Addr().String()
}
// Serve starts serving and blocks.
func (s *Server) Serve() error {
err := s.Server.Serve(s.listener)
if err != nil {
return fmt.Errorf("serving failed: %w", err)
}
return nil
}
// Close stops the gRPC server. It immediately closes all open
// connections and listeners.
// It cancels all active RPCs on the server side and the corresponding
// pending RPCs on the client side will get notified by connection
// errors.
func (s *Server) Close() {
s.Server.Stop()
for _, f := range s.closeFunc {
f()
}
}