forked from devimteam/microgen
/
main.go
133 lines (121 loc) · 4.12 KB
/
main.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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// Microgen appends missed functions.
package main
import (
"context"
"errors"
"fmt"
protobuf "github.com/devimteam/microgen/examples/protobuf"
service "github.com/devimteam/microgen/examples/usersvc/pkg/service"
transport "github.com/devimteam/microgen/examples/usersvc/pkg/transport"
grpc "github.com/devimteam/microgen/examples/usersvc/pkg/transport/grpc"
http "github.com/devimteam/microgen/examples/usersvc/pkg/transport/http"
usersvc "github.com/devimteam/microgen/examples/usersvc/pkg/usersvc"
log "github.com/go-kit/kit/log"
opentracinggo "github.com/opentracing/opentracing-go"
errgroup "golang.org/x/sync/errgroup"
grpc1 "google.golang.org/grpc"
"io"
"net"
http1 "net/http"
"os"
"os/signal"
"syscall"
)
func main() {
logger := log.With(InitLogger(os.Stdout), "level", "info")
errorLogger := log.With(InitLogger(os.Stderr), "level", "error")
logger.Log("message", "Hello, I am alive")
defer logger.Log("message", "goodbye, good luck")
g, ctx := errgroup.WithContext(context.Background())
g.Go(func() error {
return InterruptHandler(ctx)
})
var svc usersvc.UserService // TODO: = service.NewUserService () // Create new service.
svc = service.LoggingMiddleware(logger)(svc) // Setup service logging.
svc = service.ErrorLoggingMiddleware(logger)(svc) // Setup error logging.
svc = service.RecoveringMiddleware(errorLogger)(svc) // Setup service recovering.
endpoints := transport.Endpoints(svc)
endpoints = transport.TraceServerEndpoints(endpoints, opentracinggo.NoopTracer{}) // TODO: Add tracer
grpcAddr := ":8081" // TODO: use normal address
// Start grpc server.
g.Go(func() error {
return ServeGRPC(ctx, &endpoints, grpcAddr, log.With(logger, "transport", "GRPC"))
})
httpAddr := ":8080" // TODO: use normal address
// Start http server.
g.Go(func() error {
return ServeHTTP(ctx, &endpoints, httpAddr, log.With(logger, "transport", "HTTP"))
})
if err := g.Wait(); err != nil {
logger.Log("error", err)
}
}
// InitLogger initialize go-kit JSON logger with timestamp and caller.
func InitLogger(writer io.Writer) log.Logger {
logger := log.NewJSONLogger(writer)
logger = log.With(logger, "@timestamp", log.DefaultTimestampUTC)
logger = log.With(logger, "caller", log.DefaultCaller)
return logger
}
// InterruptHandler handles first SIGINT and SIGTERM and returns it as error.
func InterruptHandler(ctx context.Context) error {
interruptHandler := make(chan os.Signal, 1)
signal.Notify(interruptHandler, syscall.SIGINT, syscall.SIGTERM)
select {
case sig := <-interruptHandler:
return fmt.Errorf("signal received: %v", sig.String())
case <-ctx.Done():
return errors.New("signal listener: context canceled")
}
}
// ServeGRPC starts new GRPC server on address and sends first error to channel.
func ServeGRPC(ctx context.Context, endpoints *transport.EndpointsSet, addr string, logger log.Logger) error {
listener, err := net.Listen("tcp", addr)
if err != nil {
return err
}
// Here you can add middlewares for grpc server.
server := grpc.NewGRPCServer(endpoints,
logger,
opentracinggo.NoopTracer{}, // TODO: Add tracer
)
grpcServer := grpc1.NewServer()
protobuf.RegisterUserServiceServer(grpcServer, server)
logger.Log("listen on", addr)
ch := make(chan error)
go func() {
ch <- grpcServer.Serve(listener)
}()
select {
case err := <-ch:
return fmt.Errorf("grpc server: serve: %v", err)
case <-ctx.Done():
grpcServer.GracefulStop()
return errors.New("grpc server: context canceled")
}
}
// ServeHTTP starts new HTTP server on address and sends first error to channel.
func ServeHTTP(ctx context.Context, endpoints *transport.EndpointsSet, addr string, logger log.Logger) error {
handler := http.NewHTTPHandler(endpoints,
logger,
opentracinggo.NoopTracer{}, // TODO: Add tracer
)
httpServer := &http1.Server{
Addr: addr,
Handler: handler,
}
logger.Log("listen on", addr)
ch := make(chan error)
go func() {
ch <- httpServer.ListenAndServe()
}()
select {
case err := <-ch:
if err == http1.ErrServerClosed {
return nil
}
return fmt.Errorf("http server: serve: %v", err)
case <-ctx.Done():
return httpServer.Shutdown(context.Background())
}
}