[#219] morph: Resolve containedctx linter

Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
pull/219/head
Dmitrii Stepanov 2023-04-05 16:58:32 +03:00
parent 56282edf02
commit e815b19101
9 changed files with 43 additions and 54 deletions

View File

@ -1,6 +1,8 @@
package main package main
import ( import (
"context"
accountingGRPC "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/accounting/grpc" accountingGRPC "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/accounting/grpc"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/balance" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/balance"
accountingTransportGRPC "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/network/transport/accounting/grpc" accountingTransportGRPC "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/network/transport/accounting/grpc"
@ -8,9 +10,9 @@ import (
accounting "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/accounting/morph" accounting "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/accounting/morph"
) )
func initAccountingService(c *cfg) { func initAccountingService(ctx context.Context, c *cfg) {
if c.cfgMorph.client == nil { if c.cfgMorph.client == nil {
initMorphComponents(c) initMorphComponents(ctx, c)
} }
balanceMorphWrapper, err := balance.NewFromMorph(c.cfgMorph.client, c.cfgAccounting.scriptHash, 0) balanceMorphWrapper, err := balance.NewFromMorph(c.cfgMorph.client, c.cfgAccounting.scriptHash, 0)

View File

@ -95,8 +95,8 @@ func initApp(ctx context.Context, c *cfg) {
}) })
initAndLog(c, "gRPC", initGRPC) initAndLog(c, "gRPC", initGRPC)
initAndLog(c, "netmap", initNetmapService) initAndLog(c, "netmap", func(c *cfg) { initNetmapService(ctx, c) })
initAndLog(c, "accounting", initAccountingService) initAndLog(c, "accounting", func(c *cfg) { initAccountingService(ctx, c) })
initAndLog(c, "container", func(c *cfg) { initContainerService(ctx, c) }) initAndLog(c, "container", func(c *cfg) { initContainerService(ctx, c) })
initAndLog(c, "session", initSessionService) initAndLog(c, "session", initSessionService)
initAndLog(c, "reputation", initReputationService) initAndLog(c, "reputation", initReputationService)

View File

@ -27,7 +27,7 @@ const (
notaryDepositRetriesAmount = 300 notaryDepositRetriesAmount = 300
) )
func initMorphComponents(c *cfg) { func initMorphComponents(ctx context.Context, c *cfg) {
var err error var err error
addresses := morphconfig.RPCEndpoint(c.appCfg) addresses := morphconfig.RPCEndpoint(c.appCfg)
@ -38,7 +38,8 @@ func initMorphComponents(c *cfg) {
addresses[i], addresses[j] = addresses[j], addresses[i] addresses[i], addresses[j] = addresses[j], addresses[i]
}) })
cli, err := client.New(c.key, cli, err := client.New(ctx,
c.key,
client.WithDialTimeout(morphconfig.DialTimeout(c.appCfg)), client.WithDialTimeout(morphconfig.DialTimeout(c.appCfg)),
client.WithLogger(c.log), client.WithLogger(c.log),
client.WithEndpoints(addresses...), client.WithEndpoints(addresses...),

View File

@ -2,6 +2,7 @@ package main
import ( import (
"bytes" "bytes"
"context"
"errors" "errors"
"fmt" "fmt"
@ -135,7 +136,7 @@ func (c *cfg) addressNum() int {
return 0 return 0
} }
func initNetmapService(c *cfg) { func initNetmapService(ctx context.Context, c *cfg) {
network.WriteToNodeInfo(c.localAddr, &c.cfgNodeInfo.localInfo) network.WriteToNodeInfo(c.localAddr, &c.cfgNodeInfo.localInfo)
c.cfgNodeInfo.localInfo.SetPublicKey(c.key.PublicKey().Bytes()) c.cfgNodeInfo.localInfo.SetPublicKey(c.key.PublicKey().Bytes())
parseAttributes(c) parseAttributes(c)
@ -144,7 +145,7 @@ func initNetmapService(c *cfg) {
readSubnetCfg(c) readSubnetCfg(c)
if c.cfgMorph.client == nil { if c.cfgMorph.client == nil {
initMorphComponents(c) initMorphComponents(ctx, c)
} }
initNetmapState(c) initNetmapState(c)

View File

@ -464,8 +464,8 @@ func createClient(ctx context.Context, p *chainParams, errChan chan<- error) (*c
} }
return client.New( return client.New(
ctx,
p.key, p.key,
client.WithContext(ctx),
client.WithLogger(p.log), client.WithLogger(p.log),
client.WithDialTimeout(p.cfg.GetDuration(p.name+".dial_timeout")), client.WithDialTimeout(p.cfg.GetDuration(p.name+".dial_timeout")),
client.WithSigner(p.sgn), client.WithSigner(p.sgn),

View File

@ -1,6 +1,7 @@
package audit package audit
import ( import (
"context"
"testing" "testing"
"time" "time"
@ -26,7 +27,7 @@ func TestAuditResults(t *testing.T) {
auditHash, err := util.Uint160DecodeStringLE(sAuditHash) auditHash, err := util.Uint160DecodeStringLE(sAuditHash)
require.NoError(t, err) require.NoError(t, err)
morphClient, err := client.New(key, client.WithEndpoints(client.Endpoint{Address: endpoint})) morphClient, err := client.New(context.Background(), key, client.WithEndpoints(client.Endpoint{Address: endpoint}))
require.NoError(t, err) require.NoError(t, err)
auditClientWrapper, err := NewFromMorph(morphClient, auditHash, 0) auditClientWrapper, err := NewFromMorph(morphClient, auditHash, 0)

View File

@ -29,10 +29,7 @@ type Option func(*cfg)
type Callback func() type Callback func()
// groups the configurations with default values. // groups the configurations with default values.
// nolint: containedctx
type cfg struct { type cfg struct {
ctx context.Context // neo-go client context
dialTimeout time.Duration // client dial timeout dialTimeout time.Duration // client dial timeout
logger *logger.Logger // logging component logger *logger.Logger // logging component
@ -57,7 +54,6 @@ const (
func defaultConfig() *cfg { func defaultConfig() *cfg {
return &cfg{ return &cfg{
ctx: context.Background(),
dialTimeout: defaultDialTimeout, dialTimeout: defaultDialTimeout,
logger: &logger.Logger{Logger: zap.L()}, logger: &logger.Logger{Logger: zap.L()},
waitInterval: defaultWaitInterval, waitInterval: defaultWaitInterval,
@ -84,7 +80,7 @@ func defaultConfig() *cfg {
// If desired option satisfies the default value, it can be omitted. // If desired option satisfies the default value, it can be omitted.
// If multiple options of the same config value are supplied, // If multiple options of the same config value are supplied,
// the option with the highest index in the arguments will be used. // the option with the highest index in the arguments will be used.
func New(key *keys.PrivateKey, opts ...Option) (*Client, error) { func New(ctx context.Context, key *keys.PrivateKey, opts ...Option) (*Client, error) {
if key == nil { if key == nil {
panic("empty private key") panic("empty private key")
} }
@ -142,20 +138,20 @@ func New(key *keys.PrivateKey, opts ...Option) (*Client, error) {
return nil, fmt.Errorf("could not create RPC actor: %w", err) return nil, fmt.Errorf("could not create RPC actor: %w", err)
} }
} else { } else {
cli.client, act, err = cli.newCli(cli.endpoints.list[0].Address) cli.client, act, err = cli.newCli(ctx, cli.endpoints.list[0].Address)
if err != nil { if err != nil {
return nil, fmt.Errorf("could not create RPC client: %w", err) return nil, fmt.Errorf("could not create RPC client: %w", err)
} }
} }
cli.setActor(act) cli.setActor(act)
go cli.notificationLoop() go cli.notificationLoop(ctx)
return cli, nil return cli, nil
} }
func (c *Client) newCli(endpoint string) (*rpcclient.WSClient, *actor.Actor, error) { func (c *Client) newCli(ctx context.Context, endpoint string) (*rpcclient.WSClient, *actor.Actor, error) {
cli, err := rpcclient.NewWS(c.cfg.ctx, endpoint, rpcclient.Options{ cli, err := rpcclient.NewWS(ctx, endpoint, rpcclient.Options{
DialTimeout: c.cfg.dialTimeout, DialTimeout: c.cfg.dialTimeout,
}) })
if err != nil { if err != nil {
@ -201,21 +197,6 @@ func newClientCache() cache {
} }
} }
// WithContext returns a client constructor option that
// specifies the neo-go client context.
//
// Ignores nil value. Has no effect if WithSingleClient
// is provided.
//
// If option not provided, context.Background() is used.
func WithContext(ctx context.Context) Option {
return func(c *cfg) {
if ctx != nil {
c.ctx = ctx
}
}
}
// WithDialTimeout returns a client constructor option // WithDialTimeout returns a client constructor option
// that specifies neo-go client dial timeout duration. // that specifies neo-go client dial timeout duration.
// //

View File

@ -1,6 +1,7 @@
package client package client
import ( import (
"context"
"sort" "sort"
"time" "time"
@ -32,7 +33,7 @@ func (e *endpoints) init(ee []Endpoint) {
e.list = ee e.list = ee
} }
func (c *Client) switchRPC() bool { func (c *Client) switchRPC(ctx context.Context) bool {
c.switchLock.Lock() c.switchLock.Lock()
defer c.switchLock.Unlock() defer c.switchLock.Unlock()
@ -41,7 +42,7 @@ func (c *Client) switchRPC() bool {
// Iterate endpoints in the order of decreasing priority. // Iterate endpoints in the order of decreasing priority.
for c.endpoints.curr = range c.endpoints.list { for c.endpoints.curr = range c.endpoints.list {
newEndpoint := c.endpoints.list[c.endpoints.curr].Address newEndpoint := c.endpoints.list[c.endpoints.curr].Address
cli, act, err := c.newCli(newEndpoint) cli, act, err := c.newCli(ctx, newEndpoint)
if err != nil { if err != nil {
c.logger.Warn("could not establish connection to the switched RPC node", c.logger.Warn("could not establish connection to the switched RPC node",
zap.String("endpoint", newEndpoint), zap.String("endpoint", newEndpoint),
@ -56,7 +57,7 @@ func (c *Client) switchRPC() bool {
c.logger.Info("connection to the new RPC node has been established", c.logger.Info("connection to the new RPC node has been established",
zap.String("endpoint", newEndpoint)) zap.String("endpoint", newEndpoint))
subs, ok := c.restoreSubscriptions(cli, newEndpoint, false) subs, ok := c.restoreSubscriptions(ctx, cli, newEndpoint, false)
if !ok { if !ok {
// new WS client does not allow // new WS client does not allow
// restoring subscription, client // restoring subscription, client
@ -74,7 +75,7 @@ func (c *Client) switchRPC() bool {
if c.cfg.switchInterval != 0 && !c.switchIsActive.Load() && if c.cfg.switchInterval != 0 && !c.switchIsActive.Load() &&
c.endpoints.list[c.endpoints.curr].Priority != c.endpoints.list[0].Priority { c.endpoints.list[c.endpoints.curr].Priority != c.endpoints.list[0].Priority {
c.switchIsActive.Store(true) c.switchIsActive.Store(true)
go c.switchToMostPrioritized() go c.switchToMostPrioritized(ctx)
} }
return true return true
@ -83,7 +84,7 @@ func (c *Client) switchRPC() bool {
return false return false
} }
func (c *Client) notificationLoop() { func (c *Client) notificationLoop(ctx context.Context) {
var e any var e any
var ok bool var ok bool
@ -95,7 +96,7 @@ func (c *Client) notificationLoop() {
c.switchLock.RUnlock() c.switchLock.RUnlock()
select { select {
case <-c.cfg.ctx.Done(): case <-ctx.Done():
_ = c.UnsubscribeAll() _ = c.UnsubscribeAll()
c.close() c.close()
@ -111,17 +112,17 @@ func (c *Client) notificationLoop() {
} }
if ok { if ok {
c.routeEvent(e) c.routeEvent(ctx, e)
continue continue
} }
if !c.reconnect() { if !c.reconnect(ctx) {
return return
} }
} }
} }
func (c *Client) routeEvent(e any) { func (c *Client) routeEvent(ctx context.Context, e any) {
typedNotification := rpcclient.Notification{Value: e} typedNotification := rpcclient.Notification{Value: e}
switch e.(type) { switch e.(type) {
@ -135,7 +136,7 @@ func (c *Client) routeEvent(e any) {
select { select {
case c.notifications <- typedNotification: case c.notifications <- typedNotification:
case <-c.cfg.ctx.Done(): case <-ctx.Done():
_ = c.UnsubscribeAll() _ = c.UnsubscribeAll()
c.close() c.close()
case <-c.closeChan: case <-c.closeChan:
@ -144,7 +145,7 @@ func (c *Client) routeEvent(e any) {
} }
} }
func (c *Client) reconnect() bool { func (c *Client) reconnect(ctx context.Context) bool {
if closeErr := c.client.GetError(); closeErr != nil { if closeErr := c.client.GetError(); closeErr != nil {
c.logger.Warn("switching to the next RPC node", c.logger.Warn("switching to the next RPC node",
zap.String("reason", closeErr.Error()), zap.String("reason", closeErr.Error()),
@ -156,7 +157,7 @@ func (c *Client) reconnect() bool {
return true return true
} }
if !c.switchRPC() { if !c.switchRPC(ctx) {
c.logger.Error("could not establish connection to any RPC node") c.logger.Error("could not establish connection to any RPC node")
// could not connect to all endpoints => // could not connect to all endpoints =>
@ -173,7 +174,7 @@ func (c *Client) reconnect() bool {
return true return true
} }
func (c *Client) switchToMostPrioritized() { func (c *Client) switchToMostPrioritized(ctx context.Context) {
t := time.NewTicker(c.cfg.switchInterval) t := time.NewTicker(c.cfg.switchInterval)
defer t.Stop() defer t.Stop()
defer c.switchIsActive.Store(false) defer c.switchIsActive.Store(false)
@ -181,7 +182,7 @@ func (c *Client) switchToMostPrioritized() {
mainLoop: mainLoop:
for { for {
select { select {
case <-c.cfg.ctx.Done(): case <-ctx.Done():
return return
case <-t.C: case <-t.C:
c.switchLock.RLock() c.switchLock.RLock()
@ -207,7 +208,7 @@ mainLoop:
tryE := e.Address tryE := e.Address
cli, act, err := c.newCli(tryE) cli, act, err := c.newCli(ctx, tryE)
if err != nil { if err != nil {
c.logger.Warn("could not create client to the higher priority node", c.logger.Warn("could not create client to the higher priority node",
zap.String("endpoint", tryE), zap.String("endpoint", tryE),
@ -216,7 +217,7 @@ mainLoop:
continue continue
} }
if subs, ok := c.restoreSubscriptions(cli, tryE, true); ok { if subs, ok := c.restoreSubscriptions(ctx, cli, tryE, true); ok {
c.switchLock.Lock() c.switchLock.Lock()
// higher priority node could have been // higher priority node could have been

View File

@ -1,6 +1,8 @@
package client package client
import ( import (
"context"
"github.com/nspcc-dev/neo-go/pkg/core/block" "github.com/nspcc-dev/neo-go/pkg/core/block"
"github.com/nspcc-dev/neo-go/pkg/core/state" "github.com/nspcc-dev/neo-go/pkg/core/state"
"github.com/nspcc-dev/neo-go/pkg/neorpc" "github.com/nspcc-dev/neo-go/pkg/neorpc"
@ -227,7 +229,7 @@ type subsInfo struct {
// one contains subscription information applied to the passed cli // one contains subscription information applied to the passed cli
// and receivers for the updated subscriptions. // and receivers for the updated subscriptions.
// Does not change Client instance. // Does not change Client instance.
func (c *Client) restoreSubscriptions(cli *rpcclient.WSClient, endpoint string, background bool) (si subsInfo, ok bool) { func (c *Client) restoreSubscriptions(ctx context.Context, cli *rpcclient.WSClient, endpoint string, background bool) (si subsInfo, ok bool) {
var ( var (
err error err error
id string id string
@ -240,7 +242,7 @@ func (c *Client) restoreSubscriptions(cli *rpcclient.WSClient, endpoint string,
notificationRcv := make(chan *state.ContainedNotificationEvent) notificationRcv := make(chan *state.ContainedNotificationEvent)
notaryReqRcv := make(chan *result.NotaryRequestEvent) notaryReqRcv := make(chan *result.NotaryRequestEvent)
c.startListen(stopCh, blockRcv, notificationRcv, notaryReqRcv, background) c.startListen(ctx, stopCh, blockRcv, notificationRcv, notaryReqRcv, background)
if background { if background {
c.switchLock.RLock() c.switchLock.RLock()
@ -304,7 +306,7 @@ func (c *Client) restoreSubscriptions(cli *rpcclient.WSClient, endpoint string,
return si, true return si, true
} }
func (c *Client) startListen(stopCh <-chan struct{}, blockRcv <-chan *block.Block, func (c *Client) startListen(ctx context.Context, stopCh <-chan struct{}, blockRcv <-chan *block.Block,
notificationRcv <-chan *state.ContainedNotificationEvent, notaryReqRcv <-chan *result.NotaryRequestEvent, background bool) { notificationRcv <-chan *state.ContainedNotificationEvent, notaryReqRcv <-chan *result.NotaryRequestEvent, background bool) {
// neo-go WS client says to _always_ read notifications // neo-go WS client says to _always_ read notifications
// from its channel. Subscribing to any notification // from its channel. Subscribing to any notification
@ -335,7 +337,7 @@ func (c *Client) startListen(stopCh <-chan struct{}, blockRcv <-chan *block.Bloc
continue continue
} }
c.routeEvent(e) c.routeEvent(ctx, e)
} }
}() }()
} }