diff --git a/CHANGELOG.md b/CHANGELOG.md index 35b40b99f091..f93d61b9de63 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,11 @@ Ref: https://keepachangelog.com/en/1.0.0/ # Changelog +## [v0.43.0-rc2](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.43.0-rc2) - 2021-07-19 + +### Bug Fixes + +* (server) [#9704](https://github.com/cosmos/cosmos-sdk/pull/9704) Start GRPCWebServer in goroutine, avoid blocking other services from starting. ## [v0.43.0-rc1](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.43.0-rc1) - 2021-07-14 diff --git a/server/grpc/grpc_web.go b/server/grpc/grpc_web.go index 593779835a78..c2fc023a24f0 100644 --- a/server/grpc/grpc_web.go +++ b/server/grpc/grpc_web.go @@ -1,12 +1,15 @@ package grpc import ( + "fmt" "net/http" + "time" "github.com/improbable-eng/grpc-web/go/grpcweb" "google.golang.org/grpc" "github.com/cosmos/cosmos-sdk/server/config" + "github.com/cosmos/cosmos-sdk/server/types" ) // StartGRPCWeb starts a gRPC-Web server on the given address. @@ -28,8 +31,18 @@ func StartGRPCWeb(grpcSrv *grpc.Server, config config.Config) (*http.Server, err Addr: config.GRPCWeb.Address, Handler: http.HandlerFunc(handler), } - if err := grpcWebSrv.ListenAndServe(); err != nil { + + errCh := make(chan error) + go func() { + if err := grpcWebSrv.ListenAndServe(); err != nil { + errCh <- fmt.Errorf("[grpc] failed to serve: %w", err) + } + }() + + select { + case err := <-errCh: return nil, err + case <-time.After(types.ServerStartTime): // assume server started successfully + return grpcWebSrv, nil } - return grpcWebSrv, nil } diff --git a/server/grpc/server.go b/server/grpc/server.go index 5bc146d8d12d..40a3c7716d97 100644 --- a/server/grpc/server.go +++ b/server/grpc/server.go @@ -54,7 +54,7 @@ func StartGRPCServer(clientCtx client.Context, app types.Application, address st select { case err := <-errCh: return nil, err - case <-time.After(5 * time.Second): // assume server started successfully + case <-time.After(types.ServerStartTime): // assume server started successfully return grpcSrv, nil } } diff --git a/server/start.go b/server/start.go index 79e7bee28304..d26fc7ad7a7a 100644 --- a/server/start.go +++ b/server/start.go @@ -314,7 +314,7 @@ func startInProcess(ctx *Context, clientCtx client.Context, appCreator types.App select { case err := <-errCh: return err - case <-time.After(5 * time.Second): // assume server started successfully + case <-time.After(types.ServerStartTime): // assume server started successfully } } @@ -368,7 +368,7 @@ func startInProcess(ctx *Context, clientCtx client.Context, appCreator types.App select { case err := <-errCh: return err - case <-time.After(5 * time.Second): // assume server started successfully + case <-time.After(types.ServerStartTime): // assume server started successfully } } diff --git a/server/types/app.go b/server/types/app.go index ba702074b2a6..cf6b6ad9a1ff 100644 --- a/server/types/app.go +++ b/server/types/app.go @@ -3,6 +3,7 @@ package types import ( "encoding/json" "io" + "time" "github.com/gogo/protobuf/grpc" "github.com/spf13/cobra" @@ -16,6 +17,10 @@ import ( "github.com/cosmos/cosmos-sdk/server/config" ) +// ServerStartTime defines the time duration that the server need to stay running after startup +// for the startup be considered successful +const ServerStartTime = 5 * time.Second + type ( // AppOptions defines an interface that is passed into an application // constructor, typically used to set BaseApp options that are either supplied diff --git a/testutil/network/util.go b/testutil/network/util.go index c6a2bd815904..e7542113a87b 100644 --- a/testutil/network/util.go +++ b/testutil/network/util.go @@ -16,6 +16,7 @@ import ( "github.com/cosmos/cosmos-sdk/server/api" servergrpc "github.com/cosmos/cosmos-sdk/server/grpc" + srvtypes "github.com/cosmos/cosmos-sdk/server/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" "github.com/cosmos/cosmos-sdk/x/genutil" @@ -90,7 +91,7 @@ func startInProcess(cfg Config, val *Validator) error { select { case err := <-errCh: return err - case <-time.After(5 * time.Second): // assume server started successfully + case <-time.After(srvtypes.ServerStartTime): // assume server started successfully } val.api = apiSrv @@ -105,21 +106,10 @@ func startInProcess(cfg Config, val *Validator) error { val.grpc = grpcSrv if val.AppConfig.GRPCWeb.Enable { - errCh1 := make(chan error) - go func() { - grpcWeb, err := servergrpc.StartGRPCWeb(grpcSrv, *val.AppConfig) - if err != nil { - errCh1 <- err - } - - val.grpcWeb = grpcWeb - }() - select { - case err := <-errCh1: + val.grpcWeb, err = servergrpc.StartGRPCWeb(grpcSrv, *val.AppConfig) + if err != nil { return err - case <-time.After(5 * time.Second): // assume server started successfully } - } }