Skip to content

Commit db79cf3

Browse files
committed
ING-1429: Ensure resources are release during shutdown
1 parent 66cdf41 commit db79cf3

5 files changed

Lines changed: 241 additions & 125 deletions

File tree

cmd/gateway/main.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ func init() {
9494
configFlags.String("dapi-cert", "", "path to data api tls cert for Data API")
9595
configFlags.String("dapi-key", "", "path to data api private tls key for Data API")
9696
configFlags.Int("rate-limit", 0, "specifies the maximum requests per second to allow")
97+
configFlags.Duration("shutdown-timeout", 30*time.Second, "the graceful shutdown timeout")
9798
configFlags.String("otlp-endpoint", "", "opentelemetry endpoint to send telemetry to")
9899
configFlags.Bool("disable-traces", false, "disable tracing")
99100
configFlags.Bool("disable-metrics", false, "disable metrics")
@@ -269,6 +270,7 @@ type config struct {
269270
clusterCaCertPath string
270271
clientCaCertPath string
271272
rateLimit int
273+
shutdownTimeout time.Duration
272274
otlpEndpoint string
273275
disableTraces bool
274276
disableMetrics bool
@@ -312,6 +314,7 @@ func readConfig(logger *zap.Logger) *config {
312314
clusterCaCertPath: viper.GetString("cluster-cert"),
313315
clientCaCertPath: viper.GetString("client-ca-cert"),
314316
rateLimit: viper.GetInt("rate-limit"),
317+
shutdownTimeout: viper.GetDuration("shutdown-timeout"),
315318
otlpEndpoint: viper.GetString("otlp-endpoint"),
316319
disableTraces: viper.GetBool("disable-traces"),
317320
disableMetrics: viper.GetBool("disable-metrics"),
@@ -354,6 +357,7 @@ func readConfig(logger *zap.Logger) *config {
354357
zap.String("dapiKeyPath", config.dapiKeyPath),
355358
zap.String("clusterCaCertPath", config.clusterCaCertPath),
356359
zap.Int("rateLimit", config.rateLimit),
360+
zap.Duration("shutdownTimeout", config.shutdownTimeout),
357361
zap.String("otlpEndpoint", config.otlpEndpoint),
358362
zap.Bool("disableTraces", config.disableTraces),
359363
zap.Bool("disableMetrics", config.disableMetrics),
@@ -645,6 +649,7 @@ func startGateway() {
645649
BindDapiPort: config.dapiPort,
646650
BindAddress: config.bindAddress,
647651
RateLimit: config.rateLimit,
652+
ShutdownTimeout: config.shutdownTimeout,
648653
GrpcCertificate: grpcCertificate,
649654
DapiCertificate: dapiCertificate,
650655
ClusterCaCert: caCertPool,
@@ -684,8 +689,9 @@ func startGateway() {
684689

685690
if newConfig.bindAddress != config.bindAddress ||
686691
newConfig.dataPort != config.dataPort ||
687-
newConfig.dapiPort != config.dapiPort {
688-
logger.Warn("config changes for bindAddress, dataPort or dapiPort require a restart")
692+
newConfig.dapiPort != config.dapiPort ||
693+
newConfig.shutdownTimeout != config.shutdownTimeout {
694+
logger.Warn("config changes for bindAddress, dataPort, dapiPort or shutdownTimeout require a restart")
689695
}
690696

691697
if newConfig.selfSign != config.selfSign {

gateway/gateway.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@ type Config struct {
6666
AdvertiseAddress string
6767
AdvertisePorts ServicePorts
6868

69-
RateLimit int
69+
RateLimit int
70+
ShutdownTimeout time.Duration
7071

7172
GrpcCertificate tls.Certificate
7273
DapiCertificate tls.Certificate
@@ -409,6 +410,9 @@ func (g *Gateway) Run(ctx context.Context) error {
409410
Password: config.Password,
410411
})
411412

413+
ctx, cancel := context.WithCancel(ctx)
414+
defer cancel()
415+
412416
config.Logger.Info("initializing protostellar system")
413417
gatewaySys, err := system.NewSystem(&system.SystemOptions{
414418
Logger: config.Logger.Named("gateway-system"),
@@ -430,8 +434,9 @@ func (g *Gateway) Run(ctx context.Context) error {
430434
ClientCAs: config.ClientCaCert,
431435
ClientAuth: tls.VerifyClientCertIfGiven,
432436
},
433-
AlphaEndpoints: config.AlphaEndpoints,
434-
Debug: config.Debug,
437+
ShutdownTimeout: config.ShutdownTimeout,
438+
AlphaEndpoints: config.AlphaEndpoints,
439+
Debug: config.Debug,
435440
})
436441
if err != nil {
437442
config.Logger.Error("error creating legacy proxy")

gateway/system/system.go

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ import (
4646
)
4747

4848
const maxMsgSize = 25 * 1024 * 1024 // 25MiB
49+
const defaultShutdownTimeout = time.Second * 30
4950

5051
type SystemOptions struct {
5152
Logger *zap.Logger
@@ -59,13 +60,17 @@ type SystemOptions struct {
5960
DapiTlsConfig *tls.Config
6061
AlphaEndpoints bool
6162
Debug bool
63+
64+
ShutdownTimeout time.Duration
6265
}
6366

6467
type System struct {
6568
logger *zap.Logger
6669

6770
dataServer *grpc.Server
6871
dapiServer *http.Server
72+
73+
shutdownTimeout time.Duration
6974
}
7075

7176
func NewSystem(opts *SystemOptions) (*System, error) {
@@ -238,10 +243,16 @@ func NewSystem(opts *SystemOptions) (*System, error) {
238243
TLSConfig: opts.DapiTlsConfig,
239244
}
240245

246+
if opts.ShutdownTimeout == 0 {
247+
opts.Logger.Warn("no shutdown timeout configured using default", zap.Duration("shutdownTimeout", defaultShutdownTimeout))
248+
opts.ShutdownTimeout = defaultShutdownTimeout
249+
}
250+
241251
s := &System{
242-
logger: opts.Logger,
243-
dataServer: dataSrv,
244-
dapiServer: dapiSrv,
252+
logger: opts.Logger,
253+
dataServer: dataSrv,
254+
dapiServer: dapiSrv,
255+
shutdownTimeout: opts.ShutdownTimeout,
245256
}
246257

247258
return s, nil
@@ -289,7 +300,20 @@ func (s *System) Shutdown() {
289300
wg.Add(1)
290301
go func() {
291302
defer wg.Done()
292-
s.dataServer.GracefulStop()
303+
304+
// GracefulStop has no timeout mechanism so we need to take this approach
305+
done := make(chan struct{})
306+
go func() {
307+
s.dataServer.GracefulStop()
308+
close(done)
309+
}()
310+
311+
select {
312+
case <-done:
313+
case <-time.After(s.shutdownTimeout):
314+
s.logger.Warn("data server shutdown timed out, forcing stop")
315+
s.dataServer.Stop()
316+
}
293317
}()
294318
}
295319

@@ -299,7 +323,13 @@ func (s *System) Shutdown() {
299323
defer wg.Done()
300324
s.dapiServer.SetKeepAlivesEnabled(false)
301325
time.Sleep(time.Second * 5)
302-
_ = s.dapiServer.Shutdown(context.Background())
326+
ctx, cancel := context.WithTimeout(context.Background(), s.shutdownTimeout)
327+
defer cancel()
328+
err := s.dapiServer.Shutdown(ctx)
329+
if err != nil {
330+
s.logger.Warn("data api server shutdown failed", zap.Error(err))
331+
_ = s.dapiServer.Close()
332+
}
303333
}()
304334
}
305335

gateway/test/dapi_graceful_shutdown_test.go

Lines changed: 0 additions & 115 deletions
This file was deleted.

0 commit comments

Comments
 (0)