From 452a50e9d579dd95c7e5e02bbaa35c0ecdcf41c8 Mon Sep 17 00:00:00 2001 From: Leonard Lyubich Date: Mon, 3 Oct 2022 14:13:48 +0400 Subject: [PATCH] [#343] client: Accept context parameter in `Dial` In previous implementation of `Client.Dial` there was no ability to specify parent context (e.g. global application context). Add `PrmDial.SetContext` method which accepts optional base dial context. Use the context to open client connection or fall back to using `context.Background()`. Upgraded version of `github.com/nspcc-dev/neofs-api-go/v2` module also fixes the problem when dial timeout didn't work properly. Signed-off-by: Leonard Lyubich --- client/client.go | 24 +++++++++++++++++++++++- client/client_test.go | 29 +++++++++++++++++++++++++++++ go.mod | 2 +- go.sum | 4 ++-- 4 files changed, 55 insertions(+), 4 deletions(-) diff --git a/client/client.go b/client/client.go index 4e24a22..46c4fa3 100644 --- a/client/client.go +++ b/client/client.go @@ -1,8 +1,10 @@ package client import ( + "context" "crypto/ecdsa" "crypto/tls" + "errors" "time" v2accounting "github.com/nspcc-dev/neofs-api-go/v2/accounting" @@ -63,6 +65,10 @@ func (c *Client) Init(prm PrmInit) { // Returns an error describing failure reason. If failed, the Client // SHOULD NOT be used. // +// Uses the context specified by SetContext if it was called with non-nil +// argument, otherwise context.Background() is used. Dial returns context +// errors, see context package docs for details. +// // Panics if required parameters are set incorrectly, look carefully // at the method documentation. // @@ -100,7 +106,13 @@ func (c *Client) Dial(prm PrmDial) error { c.setNeoFSAPIServer((*coreServer)(&c.c)) // TODO: (neofs-api-go#382) perform generic dial stage of the client.Client - _, _ = rpc.Balance(&c.c, new(v2accounting.BalanceRequest)) + _, err := rpc.Balance(&c.c, new(v2accounting.BalanceRequest), + client.WithContext(prm.parentCtx), + ) + // return context errors since they signal about dial problem + if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) { + return err + } return nil } @@ -174,6 +186,8 @@ type PrmDial struct { streamTimeoutSet bool streamTimeout time.Duration + + parentCtx context.Context } // SetServerURI sets server URI in the NeoFS network. @@ -214,3 +228,11 @@ func (x *PrmDial) SetStreamTimeout(timeout time.Duration) { x.streamTimeoutSet = true x.streamTimeout = timeout } + +// SetContext allows to specify optional base context within which connection +// should be established. +// +// Context SHOULD NOT be nil. +func (x *PrmDial) SetContext(ctx context.Context) { + x.parentCtx = ctx +} diff --git a/client/client_test.go b/client/client_test.go index e515f80..a9f1001 100644 --- a/client/client_test.go +++ b/client/client_test.go @@ -1,6 +1,7 @@ package client import ( + "context" "crypto/ecdsa" "crypto/elliptic" "crypto/rand" @@ -37,3 +38,31 @@ func newClient(server neoFSAPIServer) *Client { return &c } + +func TestClient_DialContext(t *testing.T) { + var c Client + + // try to connect to any host + var prm PrmDial + prm.SetServerURI("localhost:8080") + + assert := func(ctx context.Context, errExpected error) { + // use the particular context + prm.SetContext(ctx) + + // expect particular context error according to Dial docs + require.ErrorIs(t, c.Dial(prm), errExpected) + } + + // create pre-abandoned context + ctx, cancel := context.WithCancel(context.Background()) + cancel() + + assert(ctx, context.Canceled) + + // create "pre-deadlined" context + ctx, cancel = context.WithTimeout(context.Background(), 0) + defer cancel() + + assert(ctx, context.DeadlineExceeded) +} diff --git a/go.mod b/go.mod index b19336a..f3b1702 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/mr-tron/base58 v1.2.0 github.com/nspcc-dev/hrw v1.0.9 github.com/nspcc-dev/neo-go v0.99.2 - github.com/nspcc-dev/neofs-api-go/v2 v2.13.2-0.20221004142957-5fc2644c680d + github.com/nspcc-dev/neofs-api-go/v2 v2.13.2-0.20221005093543-3a91383f24a9 github.com/nspcc-dev/neofs-contract v0.15.3 github.com/nspcc-dev/tzhash v1.6.1 github.com/stretchr/testify v1.7.0 diff --git a/go.sum b/go.sum index 2a15a9a..f423eff 100644 --- a/go.sum +++ b/go.sum @@ -263,8 +263,8 @@ github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220809123759-3094d3e0c14b h1:J7 github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220809123759-3094d3e0c14b/go.mod h1:23bBw0v6pBYcrWs8CBEEDIEDJNbcFoIh8pGGcf2Vv8s= github.com/nspcc-dev/neofs-api-go/v2 v2.11.0-pre.0.20211201134523-3604d96f3fe1/go.mod h1:oS8dycEh8PPf2Jjp6+8dlwWyEv2Dy77h/XhhcdxYEFs= github.com/nspcc-dev/neofs-api-go/v2 v2.11.1/go.mod h1:oS8dycEh8PPf2Jjp6+8dlwWyEv2Dy77h/XhhcdxYEFs= -github.com/nspcc-dev/neofs-api-go/v2 v2.13.2-0.20221004142957-5fc2644c680d h1:Oc15A8gDoP/TC5kdJi6TW9AnOp5dYiecZ0tJDRUV7vg= -github.com/nspcc-dev/neofs-api-go/v2 v2.13.2-0.20221004142957-5fc2644c680d/go.mod h1:DRIr0Ic1s+6QgdqmNFNLIqMqd7lNMJfYwkczlm1hDtM= +github.com/nspcc-dev/neofs-api-go/v2 v2.13.2-0.20221005093543-3a91383f24a9 h1:c9ovp4KuPyIBx4dVG4bmkePlmuN0au4BBtFGXALWFBM= +github.com/nspcc-dev/neofs-api-go/v2 v2.13.2-0.20221005093543-3a91383f24a9/go.mod h1:DRIr0Ic1s+6QgdqmNFNLIqMqd7lNMJfYwkczlm1hDtM= github.com/nspcc-dev/neofs-contract v0.15.3 h1:7+NwyTtxFAnIevz0hR/XxQf6R2Ej2scjVR2bnnJnhBM= github.com/nspcc-dev/neofs-contract v0.15.3/go.mod h1:BXVZUZUJxrmmDETglXHI8+5DSgn84B9y5DoSWqEjYCs= github.com/nspcc-dev/neofs-crypto v0.2.0/go.mod h1:F/96fUzPM3wR+UGsPi3faVNmFlA9KAEAUQR7dMxZmNA=