Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
gitpod-io
GitHub Repository: gitpod-io/gitpod
Path: blob/main/components/common-go/baseserver/options.go
2498 views
1
// Copyright (c) 2022 Gitpod GmbH. All rights reserved.
2
// Licensed under the GNU Affero General Public License (AGPL).
3
// See License.AGPL.txt in the project root for license information.
4
5
package baseserver
6
7
import (
8
"context"
9
"fmt"
10
"time"
11
12
"github.com/gitpod-io/gitpod/common-go/log"
13
"github.com/heptiolabs/healthcheck"
14
"github.com/prometheus/client_golang/prometheus"
15
"github.com/sirupsen/logrus"
16
"google.golang.org/grpc/health/grpc_health_v1"
17
)
18
19
type options struct {
20
logger *logrus.Entry
21
22
// version is the version of this application
23
version string
24
25
config *Configuration
26
27
// closeTimeout is the amount we allow for the server to shut down cleanly
28
closeTimeout time.Duration
29
30
underTest bool
31
32
// metricsRegistry configures the metrics registry to use for exporting metrics. When not set, the default prometheus registry is used.
33
metricsRegistry *prometheus.Registry
34
35
healthHandler healthcheck.Handler
36
37
grpcHealthCheck grpc_health_v1.HealthServer
38
}
39
40
func defaultOptions() *options {
41
return &options{
42
logger: log.New(),
43
version: "unknown",
44
config: &Configuration{
45
Services: ServicesConfiguration{
46
GRPC: nil, // disabled by default
47
HTTP: nil, // disabled by default
48
},
49
},
50
51
closeTimeout: 5 * time.Second,
52
healthHandler: healthcheck.NewHandler(),
53
metricsRegistry: prometheus.NewRegistry(),
54
grpcHealthCheck: &GrpcHealthService{},
55
}
56
}
57
58
type Option func(opts *options) error
59
60
// WithConfig uses a config struct to initialise the services
61
func WithConfig(config *Configuration) Option {
62
return func(opts *options) error {
63
opts.config = config
64
return nil
65
}
66
}
67
68
func WithVersion(version string) Option {
69
return func(opts *options) error {
70
opts.version = version
71
return nil
72
}
73
}
74
75
func WithUnderTest() Option {
76
return func(opts *options) error {
77
opts.underTest = true
78
return nil
79
}
80
}
81
82
// WithHTTP configures and enables the HTTP server.
83
func WithHTTP(cfg *ServerConfiguration) Option {
84
return func(opts *options) error {
85
opts.config.Services.HTTP = cfg
86
return nil
87
}
88
}
89
90
// WithGRPC configures and enables the GRPC server.
91
func WithGRPC(cfg *ServerConfiguration) Option {
92
return func(opts *options) error {
93
opts.config.Services.GRPC = cfg
94
return nil
95
}
96
}
97
98
func WithLogger(logger *logrus.Entry) Option {
99
return func(opts *options) error {
100
if logger == nil {
101
return fmt.Errorf("nil logger specified")
102
}
103
104
opts.logger = logger
105
return nil
106
}
107
}
108
109
func WithCloseTimeout(d time.Duration) Option {
110
return func(opts *options) error {
111
opts.closeTimeout = d
112
return nil
113
}
114
}
115
116
func WithMetricsRegistry(r *prometheus.Registry) Option {
117
return func(opts *options) error {
118
if r == nil {
119
return fmt.Errorf("nil prometheus registry received")
120
}
121
122
opts.metricsRegistry = r
123
return nil
124
}
125
}
126
127
func WithHealthHandler(handler healthcheck.Handler) Option {
128
return func(opts *options) error {
129
if handler == nil {
130
return fmt.Errorf("nil healthcheck handler provided")
131
}
132
133
opts.healthHandler = handler
134
return nil
135
}
136
}
137
138
func WithGRPCHealthService(svc grpc_health_v1.HealthServer) Option {
139
return func(opts *options) error {
140
if svc == nil {
141
return fmt.Errorf("nil healthcheck handler provided")
142
}
143
144
opts.grpcHealthCheck = svc
145
return nil
146
}
147
}
148
149
func evaluateOptions(cfg *options, opts ...Option) (*options, error) {
150
for _, opt := range opts {
151
if err := opt(cfg); err != nil {
152
return nil, fmt.Errorf("failed to evaluate options: %w", err)
153
}
154
}
155
156
return cfg, nil
157
}
158
159
type GrpcHealthService struct {
160
grpc_health_v1.UnimplementedHealthServer
161
}
162
163
func (g *GrpcHealthService) Check(ctx context.Context, request *grpc_health_v1.HealthCheckRequest) (*grpc_health_v1.HealthCheckResponse, error) {
164
return &grpc_health_v1.HealthCheckResponse{Status: grpc_health_v1.HealthCheckResponse_SERVING}, nil
165
}
166
167