[#730] node/morph: Use disable_cache config param

Do not init caches for eACL, containers and netmap
if `disable_cache` config options is `true`, use
direct RPC calls instead.

Signed-off-by: Pavel Karpy <carpawell@nspcc.ru>
This commit is contained in:
Pavel Karpy 2021-07-29 18:57:53 +03:00 committed by Alex Vanin
parent c423aa432a
commit e8665f6cef
10 changed files with 63 additions and 25 deletions

View file

@ -3,6 +3,10 @@ Changelog for NeoFS Node
## [Unreleased]
### Upgrading from v0.23.0
Added `NEOFS_MORPH_DISABLE_CACHE` env. If `true`, none of
the `eACL`/`netmap`/`container` RPC responses cached.
## [0.23.0] - 2021-07-23 - Wando (완도, 莞島)
Improved stability for notary disabled environment.

View file

@ -159,7 +159,7 @@ func (s *ttlContainerStorage) Get(cid *cid.ID) (*containerSDK.Container, error)
type ttlEACLStorage ttlNetCache
func newCachedEACLStorage(v eacl.Storage) eacl.Storage {
func newCachedEACLStorage(v eacl.Source) eacl.Source {
const (
eaclCacheSize = 100
eaclCacheTTL = 30 * time.Second

View file

@ -127,6 +127,8 @@ type cfgGRPC struct {
type cfgMorph struct {
client *client.Client
disableCache bool
blockTimers []*timer.BlockTimer // all combined timers
eigenTrustTimer *timer.BlockTimer // timer for EigenTrust iterations
}
@ -165,9 +167,9 @@ type cfgNodeInfo struct {
}
type cfgObject struct {
netMapStorage netmapCore.Source
netMapSource netmapCore.Source
cnrStorage container.Source
cnrSource container.Source
cnrClient *cntwrapper.Wrapper

View file

@ -43,7 +43,15 @@ func initContainerService(c *cfg) {
cnrSrc := wrapper.AsContainerSource(wrap)
c.cfgObject.cnrStorage = newCachedContainerStorage(cnrSrc) // use RPC node as source of containers (with caching)
var containerSource containerCore.Source
if c.cfgMorph.disableCache {
containerSource = cnrSrc
} else {
containerSource = newCachedContainerStorage(cnrSrc) // use RPC node as source of containers (with caching)
}
c.cfgObject.cnrSource = containerSource
c.cfgObject.cnrClient = wrap
localMetrics := &localStorageLoad{

View file

@ -9,6 +9,7 @@ import (
"github.com/nspcc-dev/neo-go/pkg/util"
mainchainconfig "github.com/nspcc-dev/neofs-node/cmd/neofs-node/config/mainchain"
morphconfig "github.com/nspcc-dev/neofs-node/cmd/neofs-node/config/morph"
"github.com/nspcc-dev/neofs-node/pkg/core/netmap"
"github.com/nspcc-dev/neofs-node/pkg/morph/client"
"github.com/nspcc-dev/neofs-node/pkg/morph/client/netmap/wrapper"
"github.com/nspcc-dev/neofs-node/pkg/morph/event"
@ -61,7 +62,18 @@ func initMorphComponents(c *cfg) {
wrap, err := wrapper.NewFromMorph(c.cfgMorph.client, c.cfgNetmap.scriptHash, 0)
fatalOnErr(err)
c.cfgObject.netMapStorage = newCachedNetmapStorage(c.cfgNetmap.state, wrap)
var netmapSource netmap.Source
c.cfgMorph.disableCache = morphconfig.DisableCache(c.appCfg)
if c.cfgMorph.disableCache {
netmapSource = wrap
} else {
// use RPC node as source of netmap (with caching)
netmapSource = newCachedNetmapStorage(c.cfgNetmap.state, wrap)
}
c.cfgObject.netMapSource = netmapSource
c.cfgNetmap.wrapper = wrap
}

View file

@ -187,7 +187,7 @@ func initObjectService(c *cfg) {
clientConstructor := &reputationClientConstructor{
log: c.log,
nmSrc: c.cfgObject.netMapStorage,
nmSrc: c.cfgObject.netMapSource,
netState: c.cfgNetmap.state,
trustStorage: c.cfgReputation.localTrustStorage,
basicConstructor: c.clientCache,
@ -230,9 +230,9 @@ func initObjectService(c *cfg) {
pol := policer.New(
policer.WithLogger(c.log),
policer.WithLocalStorage(ls),
policer.WithContainerSource(c.cfgObject.cnrStorage),
policer.WithContainerSource(c.cfgObject.cnrSource),
policer.WithPlacementBuilder(
placement.NewNetworkMapSourceBuilder(c.cfgObject.netMapStorage),
placement.NewNetworkMapSourceBuilder(c.cfgObject.netMapSource),
),
policer.WithWorkScope(100),
policer.WithExpansionRate(10),
@ -265,7 +265,7 @@ func initObjectService(c *cfg) {
}
})
traverseGen := util.NewTraverserGenerator(c.cfgObject.netMapStorage, c.cfgObject.cnrStorage, c)
traverseGen := util.NewTraverserGenerator(c.cfgObject.netMapSource, c.cfgObject.cnrSource, c)
c.workers = append(c.workers, pol)
@ -274,8 +274,8 @@ func initObjectService(c *cfg) {
putsvc.WithClientConstructor(coreConstructor),
putsvc.WithMaxSizeSource(c),
putsvc.WithLocalStorage(ls),
putsvc.WithContainerSource(c.cfgObject.cnrStorage),
putsvc.WithNetworkMapSource(c.cfgObject.netMapStorage),
putsvc.WithContainerSource(c.cfgObject.cnrSource),
putsvc.WithNetworkMapSource(c.cfgObject.netMapSource),
putsvc.WithLocalAddressSource(c),
putsvc.WithFormatValidatorOpts(
objectCore.WithDeleteHandler(objInhumer),
@ -364,6 +364,20 @@ func initObjectService(c *cfg) {
respSvc,
)
var (
eACLSource eacl.Source
eACLFetcher = &morphEACLFetcher{
w: c.cfgObject.cnrClient,
}
)
if c.cfgMorph.disableCache {
eACLSource = eACLFetcher
} else {
// use RPC node as source of eACL (with caching)
eACLSource = newCachedEACLStorage(eACLFetcher)
}
aclSvc := acl.New(
acl.WithSenderClassifier(
acl.NewSenderClassifier(
@ -373,14 +387,12 @@ func initObjectService(c *cfg) {
),
),
acl.WithContainerSource(
c.cfgObject.cnrStorage,
c.cfgObject.cnrSource,
),
acl.WithNextService(signSvc),
acl.WithLocalStorage(ls),
acl.WithEACLValidatorOptions(
eacl.WithEACLStorage(newCachedEACLStorage(&morphEACLStorage{
w: c.cfgObject.cnrClient,
})),
eacl.WithEACLSource(eACLSource),
eacl.WithLogger(c.log),
),
acl.WithNetmapState(c.cfgNetmap.state),
@ -398,7 +410,7 @@ func initObjectService(c *cfg) {
}
}
type morphEACLStorage struct {
type morphEACLFetcher struct {
w *cntrwrp.Wrapper
}
@ -413,7 +425,7 @@ func (s *signedEACLTable) SignedDataSize() int {
return (*eaclSDK.Table)(s).ToV2().StableSize()
}
func (s *morphEACLStorage) GetEACL(cid *cid.ID) (*eaclSDK.Table, error) {
func (s *morphEACLFetcher) GetEACL(cid *cid.ID) (*eaclSDK.Table, error) {
table, err := s.w.GetEACL(cid)
if err != nil {
return nil, err

View file

@ -10,7 +10,7 @@ func WithLogger(v *logger.Logger) Option {
}
}
func WithEACLStorage(v Storage) Option {
func WithEACLSource(v Source) Option {
return func(c *cfg) {
c.storage = v
}

View file

@ -6,16 +6,16 @@ import (
bearer "github.com/nspcc-dev/neofs-api-go/v2/acl"
)
// Storage is the interface that wraps
// basic methods of extended ACL table storage.
type Storage interface {
// GetEACL reads the table from the storage by identifier.
// Source is the interface that wraps
// basic methods of extended ACL table source.
type Source interface {
// GetEACL reads the table from the source by identifier.
// It returns any error encountered.
//
// GetEACL must return exactly one non-nil value.
//
// Must return pkg/core/container.ErrEACLNotFound if requested
// eACL table is not in storage.
// eACL table is not in source.
GetEACL(*cid.ID) (*eacl.Table, error)
}

View file

@ -149,7 +149,7 @@ func TestHeadRequest(t *testing.T) {
}
validator := eacl2.NewValidator(
eacl2.WithEACLStorage(eStorage),
eacl2.WithEACLSource(eStorage),
)
require.Equal(t, eacl.ActionDeny, validator.CalculateAction(unit))

View file

@ -23,7 +23,7 @@ type Option func(*cfg)
type cfg struct {
logger *logger.Logger
storage Storage
storage Source
}
func defaultCfg() *cfg {