[#419] rpc/client: Use provided context for client dial

In previous implementation `Client` passed `context.Background()` to
`grpc.DialContext` function. This didn't allow to abort dial stage by
the given context.

Base dial context on the one provided with `WithContext` option. Fall
back to using `context.Background` if context is not specified.

Signed-off-by: Leonard Lyubich <ctulhurider@gmail.com>
This commit is contained in:
Leonard Lyubich 2022-10-03 13:34:22 +04:00 committed by LeL
parent 2b89b7e798
commit 3a91383f24
3 changed files with 19 additions and 13 deletions

View file

@ -2,26 +2,28 @@ package client
import ( import (
"context" "context"
"github.com/nspcc-dev/neofs-api-go/v2/rpc/grpc"
) )
// CallOption is a messaging session option within Protobuf RPC. // CallOption is a messaging session option within Protobuf RPC.
type CallOption func(*callParameters) type CallOption func(*callParameters)
type callParameters struct { type callParameters struct {
callOpts []grpc.CallOption ctx context.Context
} }
func defaultCallParameters() *callParameters { func defaultCallParameters() *callParameters {
return &callParameters{ return &callParameters{
callOpts: make([]grpc.CallOption, 0, 1), ctx: context.Background(),
} }
} }
// WithContext return options to specify call context. // WithContext returns option to specify call context. If provided, all network
// communications will be based on this context. Otherwise, context.Background()
// is used.
//
// Context SHOULD NOT be nil.
func WithContext(ctx context.Context) CallOption { func WithContext(ctx context.Context) CallOption {
return func(prm *callParameters) { return func(prm *callParameters) {
prm.callOpts = append(prm.callOpts, grpc.WithContext(ctx)) prm.ctx = ctx
} }
} }

View file

@ -13,9 +13,10 @@ import (
"google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/credentials/insecure"
) )
func (c *Client) createGRPCClient() (err error) { func (c *Client) createGRPCClient(ctx context.Context) (err error) {
c.gRPCClientOnce.Do(func() { c.gRPCClientOnce.Do(func() {
if err = c.openGRPCConn(); err != nil { if err = c.openGRPCConn(ctx); err != nil {
err = fmt.Errorf("open gRPC connection: %w", err)
return return
} }
@ -30,7 +31,7 @@ func (c *Client) createGRPCClient() (err error) {
var errInvalidEndpoint = errors.New("invalid endpoint options") var errInvalidEndpoint = errors.New("invalid endpoint options")
func (c *Client) openGRPCConn() error { func (c *Client) openGRPCConn(ctx context.Context) error {
if c.conn != nil { if c.conn != nil {
return nil return nil
} }
@ -47,15 +48,18 @@ func (c *Client) openGRPCConn() error {
creds = insecure.NewCredentials() creds = insecure.NewCredentials()
} }
dialCtx, cancel := context.WithTimeout(context.Background(), c.dialTimeout) dialCtx, cancel := context.WithTimeout(ctx, c.dialTimeout)
var err error var err error
c.conn, err = grpcstd.DialContext(dialCtx, c.addr, c.conn, err = grpcstd.DialContext(dialCtx, c.addr,
grpcstd.WithTransportCredentials(creds), grpcstd.WithTransportCredentials(creds),
grpcstd.WithBlock(), grpcstd.WithBlock(),
) )
cancel() cancel()
if err != nil { if err != nil {
return fmt.Errorf("open gRPC client connection: %w", err) return fmt.Errorf("gRPC dial: %w", err)
} }
return nil return nil

View file

@ -68,11 +68,11 @@ func (g rwGRPC) WriteMessage(m message.Message) error {
} }
func (c *Client) initGRPC(info common.CallMethodInfo, prm *callParameters) (MessageReadWriter, error) { func (c *Client) initGRPC(info common.CallMethodInfo, prm *callParameters) (MessageReadWriter, error) {
if err := c.createGRPCClient(); err != nil { if err := c.createGRPCClient(prm.ctx); err != nil {
return nil, err return nil, err
} }
rw, err := c.gRPCClient.Init(info, prm.callOpts...) rw, err := c.gRPCClient.Init(info, grpc.WithContext(prm.ctx))
if err != nil { if err != nil {
return nil, err return nil, err
} }