[#1936] network/cache: Handle dial errors

After an SDK update `Dial` can return an error.

Signed-off-by: Evgenii Stratonikov <evgeniy@morphbits.ru>
This commit is contained in:
Evgenii Stratonikov 2022-10-21 18:46:45 +03:00 committed by fyrchik
parent a189eca5d5
commit 8796807040
2 changed files with 29 additions and 21 deletions

View file

@ -19,6 +19,7 @@ Changelog for NeoFS Node
- Correctly handle setting ONLINE netmap status after maintenance (#1922) - Correctly handle setting ONLINE netmap status after maintenance (#1922)
- Correctly reset shard errors in `ControlService.SetShardMode` RPC (#1931) - Correctly reset shard errors in `ControlService.SetShardMode` RPC (#1931)
- Setting node's network state to `MAINTENANCE` while network settings forbid it (#1916) - Setting node's network state to `MAINTENANCE` while network settings forbid it (#1916)
- Do not panic during API client creation (#1936)
### Removed ### Removed
### Updated ### Updated

View file

@ -3,6 +3,7 @@ package cache
import ( import (
"context" "context"
"errors" "errors"
"fmt"
"sync" "sync"
rawclient "github.com/nspcc-dev/neofs-api-go/v2/rpc/client" rawclient "github.com/nspcc-dev/neofs-api-go/v2/rpc/client"
@ -29,8 +30,7 @@ func newMultiClient(addr network.AddressGroup, opts ClientCacheOpts) *multiClien
} }
} }
// note: must be wrapped into mutex lock. func (x *multiClient) createForAddress(addr network.Address) (clientcore.Client, error) {
func (x *multiClient) createForAddress(addr network.Address) clientcore.Client {
var ( var (
c client.Client c client.Client
prmInit client.PrmInit prmInit client.PrmInit
@ -58,13 +58,10 @@ func (x *multiClient) createForAddress(addr network.Address) clientcore.Client {
c.Init(prmInit) c.Init(prmInit)
err := c.Dial(prmDial) err := c.Dial(prmDial)
if err != nil { if err != nil {
// client never returns an error return nil, fmt.Errorf("can't init SDK client: %w", err)
panic(err)
} }
x.clients[addr.String()] = &c return &c, nil
return &c
} }
// updateGroup replaces current multiClient addresses with a new group. // updateGroup replaces current multiClient addresses with a new group.
@ -106,9 +103,10 @@ func (x *multiClient) iterateClients(ctx context.Context, f func(clientcore.Clie
var err error var err error
c := x.client(addr) c, err := x.client(addr)
if err == nil {
err = f(c) err = f(c)
}
success := err == nil || errors.Is(err, context.Canceled) success := err == nil || errors.Is(err, context.Canceled)
@ -231,25 +229,34 @@ func (x *multiClient) Close() error {
} }
func (x *multiClient) RawForAddress(addr network.Address, f func(client *rawclient.Client) error) error { func (x *multiClient) RawForAddress(addr network.Address, f func(client *rawclient.Client) error) error {
return x.client(addr).ExecRaw(f) c, err := x.client(addr)
if err != nil {
return err
}
return c.ExecRaw(f)
} }
func (x *multiClient) client(addr network.Address) clientcore.Client { func (x *multiClient) client(addr network.Address) (clientcore.Client, error) {
strAddr := addr.String() strAddr := addr.String()
x.mtx.RLock() x.mtx.RLock()
c, cached := x.clients[strAddr] c, cached := x.clients[strAddr]
x.mtx.RUnlock() x.mtx.RUnlock()
if !cached { if cached {
x.mtx.Lock() return c, nil
c, cached = x.clients[strAddr]
if !cached {
c = x.createForAddress(addr)
}
x.mtx.Unlock()
} }
return c x.mtx.Lock()
defer x.mtx.Unlock()
c, cached = x.clients[strAddr]
if !cached {
c, err := x.createForAddress(addr)
if err != nil {
return nil, err
}
x.clients[strAddr] = c
}
return c, nil
} }