forked from TrueCloudLab/frostfs-node
[#419] cmd/node: Cache network maps read from sidechain
Implement LRU cache of eACL tables read from sidechain. Use it as a netmap storage in neofs-node app. Current cache size is set to 10 (constant). Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
parent
f9342aa562
commit
55dec28bbb
2 changed files with 87 additions and 1 deletions
|
@ -7,7 +7,9 @@ import (
|
||||||
lru "github.com/hashicorp/golang-lru"
|
lru "github.com/hashicorp/golang-lru"
|
||||||
eaclSDK "github.com/nspcc-dev/neofs-api-go/pkg/acl/eacl"
|
eaclSDK "github.com/nspcc-dev/neofs-api-go/pkg/acl/eacl"
|
||||||
containerSDK "github.com/nspcc-dev/neofs-api-go/pkg/container"
|
containerSDK "github.com/nspcc-dev/neofs-api-go/pkg/container"
|
||||||
|
netmapSDK "github.com/nspcc-dev/neofs-api-go/pkg/netmap"
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/core/container"
|
"github.com/nspcc-dev/neofs-node/pkg/core/container"
|
||||||
|
"github.com/nspcc-dev/neofs-node/pkg/core/netmap"
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/services/object/acl/eacl"
|
"github.com/nspcc-dev/neofs-node/pkg/services/object/acl/eacl"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -78,6 +80,50 @@ func (c *ttlNetCache) get(key interface{}) (interface{}, error) {
|
||||||
return val, nil
|
return val, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// entity that provides LRU cache interface.
|
||||||
|
type lruNetCache struct {
|
||||||
|
mtx sync.Mutex
|
||||||
|
|
||||||
|
cache *lru.Cache
|
||||||
|
|
||||||
|
netRdr netValueReader
|
||||||
|
}
|
||||||
|
|
||||||
|
// complicates netValueReader with LRU caching mechanism.
|
||||||
|
func newNetworkLRUCache(sz int, netRdr netValueReader) *lruNetCache {
|
||||||
|
cache, err := lru.New(sz)
|
||||||
|
fatalOnErr(err)
|
||||||
|
|
||||||
|
return &lruNetCache{
|
||||||
|
cache: cache,
|
||||||
|
netRdr: netRdr,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// reads value by the key.
|
||||||
|
//
|
||||||
|
// updates the value from the network on cache miss.
|
||||||
|
//
|
||||||
|
// returned value should not be modified.
|
||||||
|
func (c *lruNetCache) get(key interface{}) (interface{}, error) {
|
||||||
|
c.mtx.Lock()
|
||||||
|
defer c.mtx.Unlock()
|
||||||
|
|
||||||
|
val, ok := c.cache.Get(key)
|
||||||
|
if ok {
|
||||||
|
return val, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
val, err := c.netRdr(key)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
c.cache.Add(key, val)
|
||||||
|
|
||||||
|
return val, nil
|
||||||
|
}
|
||||||
|
|
||||||
// wrapper over TTL cache of values read from the network
|
// wrapper over TTL cache of values read from the network
|
||||||
// that implements container storage.
|
// that implements container storage.
|
||||||
type ttlContainerStorage ttlNetCache
|
type ttlContainerStorage ttlNetCache
|
||||||
|
@ -141,3 +187,43 @@ func (s *ttlEACLStorage) GetEACL(cid *containerSDK.ID) (*eaclSDK.Table, error) {
|
||||||
|
|
||||||
return val.(*eaclSDK.Table), nil
|
return val.(*eaclSDK.Table), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type lruNetmapSource struct {
|
||||||
|
netState netmap.State
|
||||||
|
|
||||||
|
cache *lruNetCache
|
||||||
|
}
|
||||||
|
|
||||||
|
func newCachedNetmapStorage(s netmap.State, v netmap.Source) netmap.Source {
|
||||||
|
const netmapCacheSize = 10
|
||||||
|
|
||||||
|
lruNetmapCache := newNetworkLRUCache(netmapCacheSize, func(key interface{}) (interface{}, error) {
|
||||||
|
return v.GetNetMapByEpoch(key.(uint64))
|
||||||
|
})
|
||||||
|
|
||||||
|
return &lruNetmapSource{
|
||||||
|
netState: s,
|
||||||
|
cache: lruNetmapCache,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *lruNetmapSource) GetNetMap(diff uint64) (*netmapSDK.Netmap, error) {
|
||||||
|
return s.getNetMapByEpoch(s.netState.CurrentEpoch() - diff)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *lruNetmapSource) GetNetMapByEpoch(epoch uint64) (*netmapSDK.Netmap, error) {
|
||||||
|
return s.getNetMapByEpoch(epoch)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *lruNetmapSource) getNetMapByEpoch(epoch uint64) (*netmapSDK.Netmap, error) {
|
||||||
|
val, err := s.cache.get(epoch)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return val.(*netmapSDK.Netmap), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *lruNetmapSource) Epoch() (uint64, error) {
|
||||||
|
return s.netState.CurrentEpoch(), nil
|
||||||
|
}
|
||||||
|
|
|
@ -65,7 +65,7 @@ func initMorphComponents(c *cfg) {
|
||||||
wrap, err := wrapper.New(cli)
|
wrap, err := wrapper.New(cli)
|
||||||
fatalOnErr(err)
|
fatalOnErr(err)
|
||||||
|
|
||||||
c.cfgObject.netMapStorage = wrap
|
c.cfgObject.netMapStorage = newCachedNetmapStorage(c.cfgNetmap.state, wrap)
|
||||||
c.cfgNetmap.wrapper = wrap
|
c.cfgNetmap.wrapper = wrap
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue