From 5155fbe533824a46d13448678e07faa41e1cbf8d Mon Sep 17 00:00:00 2001 From: Prathamesh Musale Date: Thu, 29 Feb 2024 16:36:15 +0530 Subject: [PATCH] Gracefully shutdown GQL server on interrupt --- cmd/laconic2d/cmd/commands.go | 2 +- cmd/laconic2d/cmd/root.go | 2 +- gql/generated.go | 4 ++-- gql/server.go | 24 ++++++++++++++++++++---- 4 files changed, 24 insertions(+), 8 deletions(-) diff --git a/cmd/laconic2d/cmd/commands.go b/cmd/laconic2d/cmd/commands.go index aa85304a..e125ef3e 100644 --- a/cmd/laconic2d/cmd/commands.go +++ b/cmd/laconic2d/cmd/commands.go @@ -48,7 +48,7 @@ func initRootCmd(rootCmd *cobra.Command, txConfig client.TxConfig, basicManager newStartCmd := server.StartCmdWithOptions(newApp, app.DefaultNodeHome, server.StartCmdOptions{ PostSetup: func(svrCtx *server.Context, clientCtx client.Context, ctx context.Context, g *errgroup.Group) error { g.Go(func() error { - return gql.Server(clientCtx) + return gql.Server(ctx, clientCtx, svrCtx.Logger.With("module", "gql-server")) }) return nil diff --git a/cmd/laconic2d/cmd/root.go b/cmd/laconic2d/cmd/root.go index 88d21e95..1dd5627d 100644 --- a/cmd/laconic2d/cmd/root.go +++ b/cmd/laconic2d/cmd/root.go @@ -107,7 +107,7 @@ func NewRootCmd() *cobra.Command { // overwrite the block timeout cmtCfg := cmtcfg.DefaultConfig() cmtCfg.Consensus.TimeoutCommit = 3 * time.Second - cmtCfg.LogLevel = "*:error,p2p:info,state:info,auction:info,bond:info,registry:info" // better default logging + cmtCfg.LogLevel = "*:error,p2p:info,state:info,auction:info,bond:info,registry:info,gql-server:info" // better default logging return server.InterceptConfigsPreRunHandler(cmd, serverconfig.DefaultConfigTemplate, srvCfg, cmtCfg) }, diff --git a/gql/generated.go b/gql/generated.go index f87895be..b988f524 100644 --- a/gql/generated.go +++ b/gql/generated.go @@ -1004,7 +1004,7 @@ func (ec *executionContext) introspectType(name string) (*introspection.Type, er return introspection.WrapTypeFromDef(parsedSchema, parsedSchema.Types[name]), nil } -//go:embed "cerc-io/laconicd/schema.graphql" +//go:embed "cerc-io/laconic2d/schema.graphql" var sourcesFS embed.FS func sourceData(filename string) string { @@ -1016,7 +1016,7 @@ func sourceData(filename string) string { } var sources = []*ast.Source{ - {Name: "cerc-io/laconicd/schema.graphql", Input: sourceData("cerc-io/laconicd/schema.graphql"), BuiltIn: false}, + {Name: "cerc-io/laconic2d/schema.graphql", Input: sourceData("cerc-io/laconic2d/schema.graphql"), BuiltIn: false}, } var parsedSchema = gqlparser.MustLoadSchema(sources...) diff --git a/gql/server.go b/gql/server.go index 1ace5dce..faf383b8 100644 --- a/gql/server.go +++ b/gql/server.go @@ -1,9 +1,11 @@ package gql import ( + "context" "fmt" "net/http" + "cosmossdk.io/log" "github.com/99designs/gqlgen/graphql/handler" "github.com/go-chi/chi/v5" "github.com/rs/cors" @@ -13,7 +15,7 @@ import ( ) // Server configures and starts the GQL server. -func Server(ctx client.Context) error { +func Server(ctx context.Context, clientCtx client.Context, logger log.Logger) error { if !viper.GetBool("gql-server") { return nil } @@ -32,7 +34,7 @@ func Server(ctx client.Context) error { port := viper.GetString("gql-port") srv := handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: &Resolver{ - ctx: ctx, + ctx: clientCtx, logFile: logFile, }})) @@ -48,6 +50,20 @@ func Server(ctx client.Context) error { router.Handle("/api", srv) router.Handle("/graphql", srv) - fmt.Println("Connect to GraphQL playground", "url", fmt.Sprintf("http://localhost:%s", port)) - return http.ListenAndServe(":"+port, router) //nolint: all + errCh := make(chan error) + + go func() { + logger.Info(fmt.Sprintf("Connect to GraphQL playground url: http://localhost:%s", port)) + errCh <- http.ListenAndServe(":"+port, router) + }() + + select { + case <-ctx.Done(): + // Gracefully stop the GQL server. + logger.Info("Stopping GQL server...") + return nil + case err := <-errCh: + logger.Error(fmt.Sprintf("Failed to start GQL server: %s", err)) + return err + } }